Cat

如何在不等待的情況下使用命名管道

  • October 25, 2019

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

cat my_named_pipe

它將等到數據到達。如果沒有要讀取的數據,是否可以使用標誌立即退出?或者也許是我可以使用的 cat 以外的命令?

我也試過:

read val < "$my_named_pipe";

但這也會等待下一個數據塊——如果 fifo 為空,我不想等待。

為了防止cat在沒有任何作家的情況下掛起(在這種情況下,它是 fifo 的打開,而不是從中讀取,掛起),您可以執行以下操作:

cat 0<> "$my_named_pipe" <"$my_named_pipe"

第一個重定向以讀+寫模式打開,在大多數係統上,即使沒有寫入器也沒有讀取器,它也不會阻塞並實例化管道。然後第二個打開(這次是只讀的)不會阻塞,因為現在至少有一個寫入器(本身)。

僅在最新版本的0ksh93 中才需要,其中預設 fd<>從 0 更改為 1。

此外,在 中,當shell 內置ksh93時,這將不起作用,例如何時在呼叫之前或之後呼叫as 時,(我猜)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仍然必須閱讀他們的所有輸出並等到他們關閉管道的末端。您可以在非阻塞模式下打開管道,例如使用 GNUdd的:

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"

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

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