Stdout
為什麼從fifo重定向輸入時stdout不會刷新?
我有一個顯示提示消息並等待使用者輸入一些文本的程序。
$ 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_RDONLY
或O_WRONLY
設置打開 FIFO 時:
- 如果
O_NONBLOCK
設置了,一個open()
只讀的將立即返回。如果open()
目前沒有程序打開文件進行讀取,for write-only 將返回錯誤。- 如果
O_NONBLOCK
是明確的,一個open()
for read-only 將阻塞呼叫執行緒,直到一個執行緒打開文件進行寫入。for write-only將open()
阻塞呼叫執行緒,直到執行緒打開文件進行讀取。
O_NONBLOCK
所以shell在打開FIFO時顯然沒有使用。解決方案:
cat fifo | program
cat
從 FIFO 讀取直到文件結束,然後退出。 2.tail -f fifo | program
tail
從 FIFO 讀取直到文件結束,然後掛起等待更多直到終止。其中哪一個最適合您的情況取決於在另一端寫入 FIFO 的內容以及寫入方式。
第三種解決方案涉及讓程序在需要時打開 FIFO。
根據Rationale 部分
sh
,shell 必須將標準輸入設置為阻塞,因為…如果 shell 沒有重置此標誌,它將立即終止,因為還沒有可用的輸入數據,這將被視為與文件結尾相同。