如何在不等待的情況下對命名管道進行cat

如何在不等待的情況下對命名管道進行cat

如果命名管道中沒有任何內容,而我這樣做:

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 的先前目標保存在單獨的文件描述符上,這將保持管道打開。您可以透過編寫它來解決這個問題:catksh93/opt/ast/bin/bin$PATHbuiltin 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) 讀取它的速度慢,您可能會錯過一些寫入器的輸出。

另一種方法可能是在一段時間內沒有輸入時逾時,例如使用socats-T選項:

socat -u -T1 - - 0<> "$my_named_pipe" <"$my_named_pipe"

如果一秒鐘內沒有任何東西從管道中流出,它將退出。

答案2

很簡單的方法是cat在讀取 fifo 後立即終止,無論是否有資料。您可以使用 執行此操作timeout,如下所示:

timeout 2 cat my_named_pipe

上面,timeout在強制 cat 終止之前等待兩秒鐘。如果運行時命名管道中有緩衝的內容cat,它將列印到標準輸出。

也許不是最乾淨的解決方案,但可以完成工作。

希望能幫助你。

相關內容