FIFOパイプを持つこのスクリプトが終了しないのはなぜですか?

FIFOパイプを持つこのスクリプトが終了しないのはなぜですか?

このスクリプトは次のとおりです。

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

終了しません。catコマンドがパイプのコマンドを待っているとしますEOF。どうやって送りますか?

答え1

いいえ

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

これは、Linuxでパイプの読み取り+書き込みopen()がブロックされず、byの出力がパイプに入るほど小さいため、書き込みと読み取りを順次実行できるために機能します。<>test\necho

次のような大きな出力には機能しません。

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

パイプ(現在のLinuxバージョンでは64kiB)を埋め、seq他のプロセスがパイプから読み取られるまでブロックされます。これはcat完了するまで実行されないため発生しません。seq

気づく:

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

コマンドラインがパイプを開き、テストを作成してからパイプを閉じるので動作しませんecho(開いたファイル記述子がもう存在しないため、システムはパイプを破壊します)。したがって、次のcatコマンドラインは新しいパイプをインスタンス化しようとします(書き込むためにfifoファイルを開くまでブロックします)。

答え2

答えは明らかです。パイプがロックされ、echo猫に届かない!

パイプはデータを保存しません。プロセスがパイプに書き込もうとすると、パイプの反対側に何かを追加して読み取るまで書き込みを完了できません。

この特定の例を解決する1つの方法は、次を使用することです。

echo "test" > $tmppipe &

書き込みプロセスがバックグラウンドで実行されるようにします。これにより、スクリプトが実行され続け、そのスクリプトに到達してcat完了できるまで待ちます。

関連情報