2016-01-22 24 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:*嘆*。檢查頂部投票答案... –