Subprocess popen:为什么所有写入都会在子进程中同时发生?

时间:2016-01-22 23:07:38

标签: python subprocess stdin popen

我有两个脚本,一个控制另一个脚本并通过stdin与它通信。父脚本:

import subprocess
import time

p = subprocess.Popen(['python','read_from_stdin.py'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

for i in range(0,10):
    p.stdin.write(str(i))
    p.stdin.write('\r\n') # \n is not sufficient on Windows
    p.stdin.flush()
    print i
    time.sleep(1)

p.stdin.close()

子脚本(称为“read_from_stdin.py”):

import sys
import datetime

with open(datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + '.txt','w') as f:

    for line in sys.stdin:
        f.write(datetime.datetime.now().isoformat() + ' ' + line)

在子脚本创建的文件中,所有输入都具有相同的时间戳,尽管被父脚本写成了第二个,并且尽管使用了flush()。

2 个答案:

答案 0 :(得分:1)

编辑:根据Karoly Horvath的评论,不是等待EOF的情况,而是缓冲。下面的不同子脚本可以按预期工作。

我在这个问题上发现了这个问题:How do you read from stdin in Python?

答案的公平方式是:

  

其他人提出的答案:

for line in sys.stdin:
  print line
     

非常简单和pythonic,但必须注意脚本   在开始迭代输入行之前等待EOF。

此子脚本的行为符合预期:

import sys
import datetime

with open(datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + '.txt','w') as f:

    line = sys.stdin.readline()
    while line:
        f.write(datetime.datetime.now().isoformat() + ' ' + line)
        line = sys.stdin.readline()

    f.write('Finished')

答案 1 :(得分:1)

它是the read-ahead bug in Python 2for line in sys.stdin:在内部缓冲区已满之前不会产生任何结果。使用for line in iter(sys.stdin.readline, ''):来解决问题。

相关问题