Python <p stdout =“PIPE)”>当p.stdout.read(-1)被阻止时</p>

时间:2012-05-15 19:06:38

标签: python subprocess stdout popen

你好我在Python子进程模块中有问题

我想与子进程交互(例如:child的stdin,stdout)

这是儿童计划的代码

  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))但是一切都不起作用

但是,当我首先在stdin中给出字符串时,程序运行了。

我认为当程序结束时,孩子的stdout缓冲区没有填充......这只是我的意见

有关此问题的解决方案吗?

EDIT1。 当我首先执行打印字符串的程序,并等待用户的输入,如“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")

1 个答案:

答案 0 :(得分:5)

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

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

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

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