2016-01-22 47 views
2

我有两个脚本,一个控制另一个并通过stdin与它通信。父脚本:子进程popen:为什么所有的写入都会在子进程中立即发生?

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()。

回答

1

这是the read-ahead bug in Python 2for line in sys.stdin:直到其内部缓冲区已满时不会产生任何东西。使用for line in iter(sys.stdin.readline, ''):来解决它。

1

编辑:根据下面的Karoly Horvath的评论,它不是等待EOF,但有缓冲。下面的不同的子脚本确实按预期工作。

我发现关于这个问题的这样一个问题:How do you read from stdin in Python?

的答案下来一个公平的办法是:

由他人提出的答案:

for line in sys.stdin: 
    print line 

是非常简单和Python的,但必须注意的是,脚本将 等到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

只想发表:) http://stackoverflow.com/questions/8416586/turn-off-buffering它*不*等待EOF,但有*缓冲*。请更新您的答案。 –

+0

@ KarolyHorvath:它不等待EOF是正确的,但是你连接的问题是不相关的(修复'grep -line-buffered'在这里不起作用 - OP已经调用了p.stdin。齐平()')。问题是Python 2中的预读错误,在sys.stdin中有'for line。解决方法是:'对于行iter(sys.stdin.readline,'')' – jfs

+0

@ J.F.Sebastian:*叹*。检查顶部投票答案... –