2

你好,我对 Python 子进程模块有疑问

我想与子进程交互(例如:孩子的标准输入、标准输出)

这是子程序的代码

  1 #include <stdio.h>
  2 
  3 int main(){
  4         char buf[1024];
  5         printf("asdfsadfasff\n");
  6         scanf("%s",buf);
  7         printf("%s\n",buf);
  8 }

这段代码很简单,打印字符串,等待输入,打印输入字符串

接下来,python代码如下

  1 #!/usr/bin/python
  2 from subprocess import *
  3 
  4 fd = Popen(["./random"],stdin=PIPE,stdout=PIPE)
  5 print "pid = %d"%(fd.pid) # print pid
  6 result = ""
  7 result = fd.stdout.read(-1) # read
  8 print result
  9 fd.stdin.write("write write write!!!\n")
 10 result = fd.stdout.read(-1)
 11 print result

在这种情况下,我预计该程序会运行良好,但在第 7 行 (fd.stdout.read(-1) 被阻止并且无法运行

我更改了读取函数的参数(读取(-1),读取(1),读取(),读取(1024))但一切都不起作用

但是,当我首先在标准输入中给出字符串时,程序起作用了。

我认为程序结束时孩子的标准输出缓冲区没有填满......这只是我的选择

这个问题有什么解决办法吗?

编辑1。当我首先执行打印字符串的程序,然后等待用户输入,例如“sudo su”这工作得很好,我期望

我不明白为什么这个案子运作良好

  1 from subprocess import *
  2 
  3 fd = Popen(["sudo","su"],stdin=PIPE,stdout=PIPE)
  4 
  5 print fd.stdout.read(-1)
  6 print fd.stdin.write("asdfasdfas\n")
4

1 回答 1

5

子进程./random正在使用stdio,当进程的标准输出不是 tty 设备时,默认情况下会执行“完全缓冲”而不是“行缓冲”。由于 python 通过管道(不是 tty 设备)运行进程,因此程序正在缓冲其输出,而不是在scanf调用时打印它。缓冲区仅在 (a) 填满时刷新(写入标准输出);(b) 当被fflush调用显式刷新时;或 (c) 在程序退出时。

您可以修改子进程以进行显式fflush调用,或者您可以使用 Python 中的伪 tty,例如 withpexpectsh。(请注意,sh默认情况下,该模块仅使用 pty 输出,但这通常就足够了。)或者,在这种情况下,您正在运行的程序仅“看起来是交互式的”(但实际上是完全可预测的),您可以运行它与预先提供的已知输入序列:

fd = Popen(["./random"], stdin=PIPE, stdout=PIPE)
result = fd.communicate("write write write!!!\n")[0]

虽然当然你会把所有的标准输出输入混合在一起,并且必须将它打印的两行分开(在这种特殊情况下)。

于 2012-05-15T19:27:13.897 回答