Bash

為什麼這個帶有 FIFO 管道的腳本不會終止?

  • February 11, 2021

這個腳本:

#!/bin/bash
tmppipe=/tmp/temppipe
mkfifo $tmppipe
echo "test" > $tmppipe
cat $tmppipe
exit

不終止。我假設該cat命令正在等待EOF來自管道的命令;我怎麼寄一個?

不,它是

echo test > "$tmppipe" # BTW, you've got the quotes in the wrong places

掛起。更準確地說,它是在執行之前打開管道進行寫入的外殼echo

pipe是程序間通信機制,它們將用於並發執行的程序之間。在這裡,open(WR_ONLY)( >) 將阻塞,直到另一個程序open進入讀取模式。

echo test > "$tmppipe" &
cat < "$tmppipe"

將工作,因為echocat同時執行。

在 Linux 上,您可以擺脫:

exec 3<> "$tmppipe" 4< "$tmppipe"
echo test >&3
exec 3>&-
cat <&4

之所以有效,是因為管道上的 read+write opens ( <>) 在 Linux 上不會阻塞,並且test\n輸出 byecho足夠小以適合管道,因此您可以按順序進行寫入和讀取。

它不適用於更大的輸出,例如:

exec 3<> "$tmppipe" 4< "$tmppipe"
seq 100000 >&3
exec 3>&-
cat <&4

因為seq會填滿管道(在目前版本的 Linux 中為 64kiB)並阻塞,直到其他程序從該管道讀取數據,這永遠不會發生,因為在完成cat之前不會執行seq

注意:

echo test 1<> "$tmppipe"
cat < "$tmppipe"

也不起作用,因為echo命令行將打開管道,編寫測試然後關閉管道(然後系統將銷毀它,因為不再有文件描述符打開它)。因此,下一個cat命令行將嘗試實例化一個新管道(並阻塞,直到有東西打開 fifo 文件進行寫入)。

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