捕获来自python 3

时间:2018-02-23 16:09:53

标签: python python-3.x stdout

我试图从python脚本中捕获已执行命令的输出流。一切顺利,直到命令是python命令。

以下是我的函数,它们在stdout和stderr上获得具有不同回调的流:

capture_output.py

import sys
import logging
import shlex
import asyncio


async def _read_stream(stream, cb):  
    while True:
        line = await stream.readline()
        if line:
            cb(line.decode())
        else:
            break


async def _stream_subprocess(cmd, stdout_cb, stderr_cb):  
    process = await asyncio.create_subprocess_exec(*cmd,
            stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)

    await asyncio.wait([
        _read_stream(process.stdout, stdout_cb),
        _read_stream(process.stderr, stderr_cb)
    ])
    return await process.wait()


def execute(cmd, stdout_cb, stderr_cb):  
    loop = asyncio.get_event_loop()
    rc = loop.run_until_complete(
        _stream_subprocess(
            cmd,
            stdout_cb,
            stderr_cb,
    ))
    loop.close()
    return rc


def run_command(command,
                output_function=lambda x: print("STDOUT: %s" % x),
                error_handling=lambda x: print("STDERR: %s" % x),
                cwd=None):
    execute(shlex.split(command), output_function, error_handling, )


if __name__ == "__main__":
    "Get the command on 1st position and run it"
    command_str = sys.argv[1]
    run_command(command_str)

以下是外部命令的示例:

anylongrunning_script.sh

#!/bin/bash
for i in {1..5}
do
   echo "$i"
   sleep 0.5
done

如果我运行python capture_output.py "sh anylongrunning_script.sh",我会看到直播,一切进展顺利。

但是如果运行像python capture_output.py "python anylongrunning_script.py"这样的python命令:

anylongrunning_script.py

import time

for i in range(1, 6):
    print(i)
    time.sleep(0.5)

输出将在最后一个块中呈现。 你知道shell" echo"之间的区别是什么?和一个python" print"在这种情况下?

1 个答案:

答案 0 :(得分:1)

通过使用-u选项运行命令来禁用输出缓冲。试试python capture_output.py "python -u anylongrunning_script.py"

通过为子进程设置PYTHONUNBUFFERED env变量,可以确保所有python进程都使用无缓冲模式。