【问题标题】:Python subprocess.communicate() does not capture output from simple binaryPython subprocess.communicate() 不捕获简单二进制文件的输出
【发布时间】:2015-03-25 18:48:34
【问题描述】:

我正在尝试使用 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.outputself.error 中的任何内容。

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

相同的 sn-p 代码捕获 bash 脚本的输出:

#!/bin/bash
while true ; do
    printf "%s\t%s\n" "my.key" "$RANDOM"
    usleep 100000
done

两个脚本都不会自然退出 - 大约三秒钟后它们都被 self.process.kill() 杀死。

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

【问题讨论】:

  • 首先,用fflush(stdout);在你的C程序中flush outout。

标签: python c linux bash python-2.7


【解决方案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 代码即可工作,但输出将被缓冲。

【讨论】:

  • 那么如果我指定Popen(*args*, stdout=sys.stdout, stderr=sys.stderr,为什么Python 可以捕获/识别缓冲输出?有没有办法在不使用subprocess.PIPE的情况下将进程缓冲区only复制到一个新字符串中?
  • 你是说stdout=sys.stdout 显示你的输出吗?
  • 您可以使用 stdout=PIPE 并遍历 stdout.readline 但输出将被缓冲
猜你喜欢
  • 1970-01-01
  • 2013-03-17
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 2011-06-03
相关资源
最近更新 更多