2012-03-18 156 views
4

直接管我第一次有兩個文件,這是嘶嘶聲與蟒蛇

#!/usr/bin/python               
import time 

print 'started' 
time.sleep(3) 
print 'ended' 
下一其中

是吧

#!/usr/bin/python               
import sys 

for line in sys.stdin: 
    print line 

當我運行命令./fizz | ./bar我希望它打印started然後等待3秒並打印ended,但真正發生的是它在3秒後同時打印startedended。有沒有辦法獲得我想要的行爲?謝謝

回答

5

好問題。這比它應該更難一些。

問題確實在bar,具體是sys.stdin被緩衝。我嘗試使用較小的緩衝區大小打開sys.stdin,並使用python -u但這不起作用。該手冊頁有這樣一段話:

-u  Force stdin, stdout and stderr to be totally unbuffered. On 
      systems where it matters, also put stdin, stdout and stderr in 
      binary mode. Note that there is internal buffering in xread‐ 
      lines(), readlines() and file-object iterators ("for line in 
      sys.stdin") which is not influenced by this option. To work 
      around this, you will want to use "sys.stdin.readline()" inside 
      a "while 1:" loop. 

這到底是什麼工作對我來說:

#!/usr/bin/python             
import sys 
import os 

while True: 
    line = sys.stdin.readline() 
    if not line: 
     break 
    sys.stdout.write(line) # or print, doesn't matter. 
+0

+1問題,如果你認爲它是一個很好的問題:D – Doboy 2012-03-18 05:56:56

+1

@Doboy:我做到了,那是我的唯一投票:) – 2012-03-18 05:59:32

5

現在,很顯然,這個問題是在接收端,我呈現哪個我喜歡用一個替代:

#!/usr/bin/python             
import sys 
import os 

for line in iter(sys.stdin.readline, ''): 
    sys.stdout.write(line) # \n included in line 

iter(func, sentinel)呼叫每次迭代210次,並在函數結果爲== sentinel時結束。

1

有兩個問題:

  1. ./fooprint "something"不刷新其標準輸出緩衝器,如果它被重定向(到管在這種情況下),即,當stdout is not connected a tty-like device例如,以交互式控制檯
  2. for line in sys.stdin:可能會嘗試一次讀幾行

您可以修復它,如下所示:

$ PYTHONUNBUFFERED=1 ./foo | ./bar 

./bar

#!/usr/bin/python 
import sys 

for line in iter(sys.stdin.readline, ''): 
    print line, 

即,使01​​的標準輸出緩衝(-u option)並且如@Eduardo Ivanec's answer建議在./bar逐行讀取輸入。

作爲替代方法,您可以在./foo中調用sys.stdout.flush(),而不是按照@kev's answer中的建議使其標準輸出無緩衝。