Stdout

為什麼從fifo重定向輸入時stdout不會刷新?

  • June 14, 2018

我有一個顯示提示消息並等待使用者輸入一些文本的程序。

$ program
Input a line of text: <aaaa>
Some more output.
$

現在,我還希望能夠通過 FIFO 以程式方式提供此輸入,如下所示:

$ program < fifo

但是發生的事情是,在我將輸入提供給fifo.

接下來我嘗試了一個非常簡單的程序,如下所示:

$ echo aaaa < fifo

即使在這裡,aaaa也不會出現,直到fifo提供了它的輸入。

**問題:**在使用 FIFO 時,如何使我的輸出直到我等待輸入stdin出現?stdout

FIFO由shell打開,但它的打開是阻塞的,直到FIFO被其他程序打開寫入。由於重定向是在執行命令之前open()處理的,因此在 shell 的呼叫返回之前,程序甚至不會執行。這是C 庫函式(由 shell 使用)的記錄行為:open()

O_NONBLOCK

使用O_RDONLYO_WRONLY設置打開 FIFO 時:

  • 如果O_NONBLOCK設置了,一個open()只讀的將立即返回。如果open()目前沒有程序打開文件進行讀取,for write-only 將返回錯誤。
  • 如果O_NONBLOCK是明確的,一個open()for read-only 將阻塞呼叫執行緒,直到一個執行緒打開文件進行寫入。for write-only將open()阻塞呼叫執行緒,直到執行緒打開文件進行讀取。

O_NONBLOCK所以shell在打開FIFO時顯然沒有使用。

解決方案:

  1. cat fifo | program

cat從 FIFO 讀取直到文件結束,然後退出。 2. tail -f fifo | program

tail從 FIFO 讀取直到文件結束,然後掛起等待更多直到終止。

其中哪一個最適合您的情況取決於在另一端寫入 FIFO 的內容以及寫入方式。

第三種解決方案涉及讓程序在需要時打開 FIFO。


根據Rationale 部分sh,shell 必須將標準輸入設置為阻塞,因為…

如果 shell 沒有重置此標誌,它將立即終止,因為還沒有可用的輸入數據,這將被視為與文件結尾相同。

引用自:https://unix.stackexchange.com/questions/449816