2011-07-26 20 views
7

LS:Named Pipeがスクリプトの途中で終了していますか?

prwx------ 1 root root 0 fifo 

write.sh:

#! /bin/bash 
while true; 
do 
    echo "blah" > fifo 
done 

read.sh:

#! /bin/bash 
while true; 
do 
    cat fifo 
done 

は、私は1つはwrite.shを実行し、別のread.shを実行している、二つの端末を開いています。私が最初にwrite.shを起動すると、(それは必要なように)ハングします。それから私は他のターミナルに行き、read.shを開始し、"blah"を何度も印刷すると、write.shが停止します。なぜ私の書き込みスクリプトは停止していますか?これは、私がパイプにすべてのログを送るので、私はそれらを解析してファイルに書き込むことができるので、私はパイプをちょっと良くしようとする少しのテストです。

私はここで何が欠けていますか?

答えて

5

ここに競合状態があります。どちらのスクリプトが最初に内部ループコマンドを実行するか(それぞれcatとecho)はブロックし、もう一方のスクリプトが内部ループコマンドを実行するのを待ちます。しかし、スクリプトが同期した後、catがwrite()を実行する前にcatでclose()を呼び出すと、echoにSIGPIPEが送られスクリプトが終了します。読者が閉じているパイプに書き込むことはできません。

catをwhileループにする代わりにtail -fに変更すると、リーダーは永久にfifoを開いたり閉じたりするのではなく、生きていて、SIGPIPEを取得しないでください。

参照:man fifo

+0

パーフェクト!ありがとう。 – n0pe

5

あなたはまた、最初の読み出しファイルディスクリプタ、その後fifoの書き込みファイル記述子を開くことができ、ノンブロッキング配管の動作を取得します。

# cf. https://stackoverflow.com/questions/2776994/tee-a-pipe-asynchronously 
(
rm -f fifo 
mkfifo fifo 
exec 3<fifo # open fifo for reading 
trap "exit" 1 2 3 15 
exec cat fifo | nl 
) & 
bpid=$! 

(
exec 3>fifo # open fifo for writing 
trap "exit" 1 2 3 15 
while true; 
do 
    echo "blah" > fifo 
done 
) 
#kill -TERM $bpid 

も参照してください:How do I use exec 3>myfifo in a script, and not have echo foo>&3 close the pipe?

関連する問題