2012-07-02 48 views
1

我開始一個進程,並將其輸出重定向到一個命名管道。我正在使用cat > $pipe重新連接到命名管道。當進程的stdout沒有輪詢父進程死亡時,如何設置命名管道死掉?Bash:讀取/寫入命名管道的替代貓

除此之外,還有什麼除了cat可以用來打開命名管道?

+1

這很混亂。您的Java進程是讀取管道還是寫入管道?你正在爲了什麼目的使用它,將一些日誌輸出重定向到終端? –

+0

如果你的進程(最初是一個Java進程)正在寫入FIFO,你可能希望你的'cat'進程從FIFO中讀取數據,而不是寫入到另一個進程中。任何可以打開文件的進程都可以打開一個FIFO。 –

回答

4

一個FIFO總是準備讀寫,所以像cattail -f程序不會停止讀書,直到永遠。你想要檢查的是,是否有寫入該文件的進程,如果沒有這樣的進程,請停止閱讀。 (順便說一句,讀取文件的最佳方式是read它。)

lsof可以告訴你誰讀寫指定的文件。看看在它的手冊頁,並嘗試類似:

while lsof /path/to/fifo 
do 
    read -r line < /path/to/fifo 
    printf "%s\n" "$line" 
done 

我不知道,也沒有足夠的時間來考慮lsof的,找出哪些選項輸出僅處理到該文件。請在手冊頁上查看。
所以,只要有一個寫入fifo的進程,這個腳本就會讀取一行並打印出來。一旦沒有進程寫入文件,循環就會中斷並且腳本退出。

我不知道另一種方法來檢查是否有一個過程寫入文件,而不是使用lsof。如果有人知道更標準的方法,我也想知道。

+0

默認情況下,FIFO上的open()會掛起,直到有另一個進程也打開其他模式。也就是說,如果進程A打開FIFO進行寫操作,'open()'將掛起,直到進程B打開FIFO進行讀取,反之亦然。一旦打開FIFO,FIFO上的read()將掛起,直到有一些數據要讀取;如果FIFO緩衝區中沒有剩餘空間用於寫入數據(寫入的數據比讀取的數據多得多),則可能會掛起「write()」。 _ [... continue ...] _ –

+0

_ [... continuation ...] _但是,當從FIFO中讀取時,'cat'不會檢測到EOF,直到它具有(a)讀取所有數據和b)沒有任何流程可以寫作。同樣,一個'write()'不會失敗,直到沒有進程打開FIFO讀取。非阻塞I/O並打開讀取和寫入的FIFO會破壞正常行爲;要小心。 –

0

cat > $pipe寫入管道,不從中讀取。

如果您想從管道讀取數據並在終端上打印,請嘗試tail -f $pipe

-f選項保持tail運行並在將新數據寫入管道時使其打印輸出。

另請參閱來自Linux Journal的此article

+0

使用'cat> $ pipe',您可以將cat的輸出重定向到管道,換句話說,您正在寫入管道。 – Wernsey