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


8

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

すべてのコマンドは、POSIXで動作する場合、私はわからないので、私は、バッシュを使っていshたりzshksh...

タイトルで言及している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. サーバーに接続できません。サーバーは永久に待機します。

回答:


8

ここで重要なのは、FIFOを開くことがブロッキング操作であることです。open両端一度だけリターンは、FIFOが読み取りと書き込みの両方のために開いている、すなわちたら、接続されています。

男fifo(7)

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

最初のケースでは、シェルはパイプラインを実行するためにforkするため、読み取り用に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は、開始さえされておらず、ポートがリスニングのために開かれていなかったことがわかるでしょう。


ええ#3の愚かなエラーですが、最終的に結果は同じままです。何よりも好奇心の強いもう1つの質問ですが、execはr / wのfifoを1つのステップで開く唯一の方法ですか?そして、シェルに#1のようにフォークを強制する他の方法はありますか?ありがとうございました!
foo 2014年

nc ... <>fifo十分なはずです。gnu.org/software/bash/manual/html_node/Redirections.html
Mikel

1
パイプライン、サブシェル、またはプロセス置換を使用すると、シェルはいつでもフォークします。
ミケル2014年

2
fd 0の読み取りと書き込みのnc ... <>fifo >&0ために<>fifo開くので、修正が必要fifoです。出力もそこに行きたいです。
ミケル2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.