Python <p = Popen(["command"],stdout = PIPE)>当p.stdout.read(-1)被阻止时

Joo*_*Kim 2 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 }
Run Code Online (Sandbox Code Playgroud)

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

接下来,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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我预计这个程序将运行良好,但在第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")
Run Code Online (Sandbox Code Playgroud)

tor*_*rek 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]
Run Code Online (Sandbox Code Playgroud)

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