Bash
為什麼這個帶有 FIFO 管道的腳本不會終止?
這個腳本:
#!/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"
將工作,因為
echo
並cat
同時執行。在 Linux 上,您可以擺脫:
exec 3<> "$tmppipe" 4< "$tmppipe" echo test >&3 exec 3>&- cat <&4
之所以有效,是因為管道上的 read+write
open
s (<>
) 在 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 文件進行寫入)。