我正在尝试使用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.PIPE
,self.output
和self.error
是None
)。
self.process = Popen(shlex.split(self.path_to_binary), stdout=sys.stdout, stderr=sys.stderr);
self.output, self.error = self.process.communicate();
但是,如果我将stdout
和stderr
参数更改为subprocess.PIPE
,subprocess.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源?
答案 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代码的情况下工作,但输出将被缓冲。