如果命名管道中沒有任何內容,而我這樣做:
cat my_named_pipe
它將等待數據到達。如果沒有要讀取的數據,是否可以使用一個標誌立即退出?或者也許我可以使用 cat 之外的命令?
我也嘗試過:
read val < "$my_named_pipe";
但這也會等待下一個資料塊 - 如果 fifo 為空,我不想等待。
答案1
為了防止cat
在沒有任何寫入器的情況下掛起(在這種情況下,掛起的是 fifo 的打開,而不是從中讀取),您可以執行以下操作:
cat 0<> "$my_named_pipe" <"$my_named_pipe"
第一個重定向以讀取+寫入模式打開,在大多數系統上,即使沒有寫入器或讀取器,也不會阻塞並實例化管道。然後第二個打開(這次是只讀)不會阻塞,因為現在至少有一個寫入者(本身)。
僅在 ksh93 的最新版本中才0
需要,其中預設 fd<>
從 0 更改為 1。
另外,在 中,當shell 內建ksh93
時,這將不起作用,例如在調用之前或之後調用時,(我猜)ksh93 將 stdin 的先前目標保存在單獨的文件描述符上,這將保持管道打開。您可以透過編寫它來解決這個問題:cat
ksh93
/opt/ast/bin
/bin
$PATH
builtin cat
<"$my_named_pipe"
cat 3<> "$my_named_pipe" <"$my_named_pipe" 3<&-
(您可能還會認為這更清楚地傳達了意圖)
請注意,<>
管道上的其他讀取器也會解鎖 fifo。
如果有一些作家,cat
仍然必須讀取他們的所有輸出並等待他們關閉管道的末端。您可以以非阻塞模式開啟管道,就像使用 GNU 一樣dd
:
dd bs=64k if="$my_named_pipe" iflag=nonblock status=noxfer
只要管道中有一些數據,它就會從管道中讀取數據,然後退出
dd: error reading 'fifo': Resource temporarily unavailable
當沒有更多的時候會出錯,並且不會解鎖其他讀取器,但這意味著如果寫入管道的速度比您 ( dd
) 讀取它的速度慢,您可能會錯過一些寫入器的輸出。
另一種方法可能是在一段時間內沒有輸入時逾時,例如使用socat
s-T
選項:
socat -u -T1 - - 0<> "$my_named_pipe" <"$my_named_pipe"
如果一秒鐘內沒有任何東西從管道中流出,它將退出。
答案2
很簡單的方法是cat
在讀取 fifo 後立即終止,無論是否有資料。您可以使用 執行此操作timeout
,如下所示:
timeout 2 cat my_named_pipe
上面,timeout
在強制 cat 終止之前等待兩秒鐘。如果運行時命名管道中有緩衝的內容cat
,它將列印到標準輸出。
也許不是最乾淨的解決方案,但可以完成工作。
希望能幫助你。