Python subprocess.communicate()不捕获简单二进制文件的输出

时间:2015-03-25 18:48:35

标签: python c linux bash python-2.7

我正在尝试使用Python来捕获此编译的C程序的输出:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main() {
  srand(time(NULL));

  do {
    int r = rand();
    printf("%s\t%d\n", "my.key", r);
    usleep(100000);
  } while ( 1 );
}

如果我运行以下命令,我会看到我的二进制文件的输出与我期望的交错的python输出(并且因为stdout / stderr不是subprocess.PIPEself.outputself.errorNone)。

self.process = Popen(shlex.split(self.path_to_binary), stdout=sys.stdout, stderr=sys.stderr);
self.output, self.error = self.process.communicate();

但是,如果我将stdoutstderr参数更改为subprocess.PIPEsubprocess.communicate()仍然无法捕获self.output或{{1}中的任何内容}}

self.error

相同的代码片段捕获bash脚本的输出:

self.process = Popen(shlex.split(self.path_to_binary), stdout=subprocess.PIPE, stderr=subprocess.PIPE);
self.output, self.error = self.process.communicate();

两个剧本都不会自然退出 - 大约三秒后它们都会被#!/bin/bash while true ; do printf "%s\t%s\n" "my.key" "$RANDOM" usleep 100000 done 杀死。

为什么Python可以捕获bash输出而不是二进制输出?我可以在等式的 Python 方面做些什么来捕获二进制文件的输出,而不修改C源

1 个答案:

答案 0 :(得分:1)

正在缓冲输出:

你需要从c:

中清空
int main() {
  srand(time(NULL));

  do {
    int r = rand();
    printf("%s\t%d\n", "my.key", r);
    usleep(100000);
    fflush(stdout);
  } while ( 1 );
}

迭代stdout.readline,communicate正在等待进程完成,所以你不会得到任何输出:

for line in iter(p.stdout.readline,""):
    print(line)

如果你希望输出无缓冲而不改变c代码,你可以在linux上使用stdbuf

p = Popen(["stdbuf","-oL","binary"], stdout=PIPE, stderr=PIPE)

for line in iter(p.stdout.readline,""):
    print(line)

-oL将进行行缓冲。

使用for line in iter(p.stdout.readline,"")可以在不更改c代码的情况下工作,但输出将被缓冲。