この質問は以下から来ています。https://mywiki.wooledge.org/ProcessSubstitution
mkfifo /var/tmp/fifo1
mkfifo /var/tmp/fifo2
sort list1 >/var/tmp/fifo1 &
sort list2 >/var/tmp/fifo2 &
diff /var/tmp/fifo1 /var/tmp/fifo2
rm /var/tmp/fifo1 /var/tmp/fifo2
名前付きパイプについて私が理解したところによると、次のことがうまくいくと思います。
行1-2では、fifo1とfifo2という2つの名前付きパイプを作成します。
sort list1 > fifo1 &
名前付きパイプへの書き込みを試みるため、sort list2 > fifo2 &
そのパイプからデータを読み取るまでブロックされます。
次に、diff
fifo1 と fifo2 から次のコマンドを読み込みます。したがって、3〜4行はスムーズに実行されます。次にdiff
実行して出力を端末に送信します。
最後に、名前付きパイプfifo1とfifo2を削除します。
消息筋はすべてがdiff <(sort list1) <(sort list2)
。
私の説明は正しいですか?
ありがとうございます!
答え1
私の説明は正しいですか?
習慣。sort
sは起動する前にブロックされます(sort
sを実行するサブシェルはsを実行しようとするとブロックされます)。開いている先に入ったものが先に出たのです)。 FIFOの反対側がブロックされるまでのみブロックされます。開いている必要ない読むそれから何も得ないでください。
試してみると、mkfifo /tmp/fifo; true > /tmp/fifo
fifotrue
に何も書き込もうとしなくてもブロックされます。他のシェルのAは試みずにtrue < /tmp/fifo
ロックを解除します。読む何もない。
消息筋はすべてが
diff <(sort list1) <(sort list2)
。
そうではありません。何らかの理由でdiff fifo1 fifo2
引数として渡されたFIFOを開く前に終了すると、sort ... &
誰かが慈悲を与え、手動で殺すまで永遠にそこにとどまります。
名前付きパイプを使用してプロセスの交換を実際に達成できるかどうかはわかりませんが、FWIW bashはsのないプラットフォームでは簡単に実装できません。/dev/fd
bashのプロセス交換にはバグがあるので、非常に注意して使用する必要があります。