このスクリプト:
#!/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"
echo test >&3
cat < "$tmppipe"
exec 3<&-
_
これは、パイプでの読み取りと書き込みopen
s(_<>
_)がLinuxではブロックされないため、およびecho
による_test\n
_出力がパイプに収まるほど小さいため、書き込みと順次読み取り。
次のようなより大きな出力では機能しません。
_exec 3<> "$tmppipe"
seq 100000 >&3
cat < "$tmppipe"
exec 3<&-
_
seq
はパイプ(現在のバージョンのLinuxでは64kiB)を満たし、他のプロセスがそのパイプからデータを読み取るまでブロックするため、cat
はseq
が完了するまで実行されないため、これは起こりません。
ご了承ください:
_echo test 1<> "$tmppipe"
cat < "$tmppipe"
_
echo
コマンドラインがパイプを開き、テストを書き込んでからパイプを閉じるため、ファイル記述子が開かれていないため、システムはパイプを破棄します。したがって、次のcat
コマンドラインは、新しいパイプをインスタンス化しようとします(書き込みのためにfifoファイルが開かれるまでブロックします)。
答えは明白です-パイプはecho
によってロックされており、猫には届きません!
パイプはデータを格納しません。プロセスがパイプに書き込もうとすると、パイプのもう一方の端に何かが接続されて読み取られるまで、書き込みを完了できません。
この特定の例を解決する方法は、使用することです
echo "test" > $tmppipe &
書き込みプロセスをバックグラウンドで実行します。このようにして、スクリプトが続行している間、cat
に到達して完了するまで待機します。