2011-11-01 84 views
3
$ cat script.py 
import sys 

for line in sys.stdin: 
    sys.stdout.write(line) 
    sys.stdout.flush() 

$ cat script.py - | python -u script.py 

的輸出是正確的,但它只是開始打印一次我按下Ctrl-d,而下開始打印的時候了:爲什麼即使在刷新和使用-u時,python仍然會緩存stdout?

$ cat script.py - | cat 

害得我以爲緩衝並非來自貓。

我設法得到它的工作做:

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

如下解釋:Streaming pipes in Python,但我不明白爲什麼如預期前解決方案不起作用。

回答

4

Python的聯機幫助揭示了回答你的問題:

-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 xreadlines(), 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. 

即:文件對象的迭代器的內部緩衝惹的禍(和它不與-u消失)。

1

如果輸出到管道,cat會默認阻止緩衝。所以當你在cat命令中包含 - (stdin)時,它會在輸出任何內容之前等待EOF(你的ctrl-D關閉標準輸入流)或8K(可能)數據。

如果將cat命令更改爲「cat script.py |」你會發現它可以按照你的預期工作。另外,如果您將8K的註釋添加到script.py的末尾,它也會立即將其打印出來。

編輯:

以上是錯誤的。 :-)

事實證明,file.next()(由文件迭代器使用,即用於文件中的行)具有readline()不使用的隱藏的預讀緩衝區,它只讀取一個字符直到它看到換行符或EOF。

+0

我編輯了我的問題,解釋它爲什麼似乎不是來自貓本身。 –

+0

你的改變沒有什麼區別......它是第一隻緩衝的貓,因爲輸出到了管道。改變管道後的水槽不會改變任何東西。您可以通過簡單地執行「cat script.py - 」來看到它,並且看到它會立即輸出script.py,因爲它將轉到終端而不是管道。 –

+0

也許我的例子並不清楚,但我認爲它表明,第一隻貓不緩衝,因爲script.py的內容在EOF發送給第一隻貓之前顯示。 –

相關問題