これら 4 つのコマンド (fifo、プロセス置換、リダイレクトなど) の違いは何ですか?

これら 4 つのコマンド (fifo、プロセス置換、リダイレクトなど) の違いは何ですか?

nc私の目標は、と単一のを使用して単純なエコー サーバーを作成することですfifo。最善の方法を探しているわけではなく、次のコマンドのセマンティクス (フォークがいつ発生するか、なぜ発生するか、何が変更されるか、コマンドの動作が異なるのはなぜかなど) を理解しようとしているだけです。

sh私は Bash を使用しているので、すべてのコマンドが POSIXまたはzsh、 、で動作するかどうかはわかりませんksh

タイトルで言及している 4 つのコマンドは次のとおりです (すでに実行済みであると仮定しますmkfifo fifo)。

cat fifo | nc -l localhost 8888 > fifo
exec 3<> fifo && nc -l localhost 8888 <&3 >&3 && exec 3>&-
nc -l localhost 8888 <(cat fifo) > fifo
nc -l localhost 8888 < fifo > fifo

ここで、4 つのコマンドが同じことを実行し、少なくとも最後の 2 つのコマンドは同じことを実行すると予想します。

  1. 最初のコマンドは期待どおりに動作し、クライアントが接続を閉じるとシャットダウンする単純なエコー サーバーになります。
  2. 1 のように動作します。
  3. サーバーに接続してデータを送信できますが、何も返ってきません。クライアント接続を閉じると、サーバーがシャットダウンします。
  4. サーバーに接続できません。サーバーは永久にリッスンし続けます。

答え1

ここで重要なのは、FIFO を開くことはブロッキング操作であるということです。open両端が接続されたとき、つまり FIFO が読み取りと書き込みの両方に対して開かれたときのみ、戻ります。

マン・フィフォ(7)

Normally, opening the FIFO blocks until the other end is opened also.

1 番目のケースでは、シェルはパイプラインを実行するためにフォークするため、読み取り用に fifo を開く ( cat fifo) ことと、書き込み用に fifo を開く ( > fifo) ことは別々のプロセスで行われるため、独立して発生します。

2 番目のケースでは、読み取り用のオープンと書き込み用のオープン ( 3<>fifo) が 1 つのステップで実行されます。

3 番目のケースでは、<(cat fifo)はファイル名に展開されます (例: ) /dev/fd/42。つまり、 を実行しているのと同じです。同等にするには、 の ようにnc -l localhost 8888 /dev/fd/42 > fifo追加の が必要です(例: ) 。<nc -l localhost 8888 < <(cat fifo) > fifo

4 番目のケースでは、シェルは fifo を読み取り用に開こうとしています ( < fifo)、> fifo同じプロセスの一部として書き込み用に開こうとしています ( )。シェルは、これらを左から右に 1 つずつ実行します。つまり、fifo読み取り用に開こうとしますが、書き込み用に何かが開くのを待って永久にブロックします。このケースでは、開始すらされず、ポートがリスニング用に開かれなかったことfifoがわかると思います。nc

関連情報