您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python逐行从子流程捕获stdout

Python逐行从子流程捕获stdout

我仅在Windows上进行了测试,但是它可以在2.6.6、2.7.2和3.2.1中运行:

from __future__ import print_function
from subprocess import PIPE, Popen
from threading  import Thread
import sys

try:
    from Queue import Queue, Empty
except ImportError:
    from queue import Queue, Empty  # python 3.x

ON_POSIX = 'posix' in sys.builtin_module_names

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        line = line.decode(sys.stdout.encoding)
        queue.put(line)
    out.close()

def main():
    p = Popen(['c/main.exe'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX)
    q = Queue()
    t = Thread(target=enqueue_output, args=(p.stdout, q))
    t.daemon = True # thread dies with the program
    t.start()

    #initially the queue is empty and stdout is open
    #stdout is closed when enqueue_output finishes
    #then continue printing until the queue is empty

    while not p.stdout.closed or not q.empty():
        try:
            line = q.get_Nowait()
        except Empty:
            continue
        else:
            print(line, end='')
    return 0

if __name__ == '__main__':
    sys.exit(main())

输出

Outputting: 0
Outputting: 1
Outputting: 2
...
Outputting: 9997
Outputting: 9998
Outputting: 9999

编辑:

readline()将阻塞,直到刷新程序的标准输出缓冲区为止,如果数据流是间歇性的,则可能需要很长时间。如果您可以编辑源代码,则一种方法是手动调用fflush(stdout),也可以在程序开始时使用setvbuf禁用缓冲。例如:

#include <stdio.h>

int main() {

    setvbuf(stdout, NULL, _IONBF, 0);

    FILE* fh = fopen("output.txt", "w");
    int i;

    for (i = 0; i < 10; i++) {
        printf("Outputting: %d\n", i);
        fprintf(fh, "Outputting: %d\n", i);
        sleep(1);
    }

    fclose(fh);
    return 0;
}

还要考虑使用unbufferstdbuf修改现有程序的输出流。

python 2022/1/1 18:36:14 有431人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶