10

特定のタスクを実行する一連のコマンドを設計しているときに、匿名パイプが期待どおりに動作しないという問題に遭遇しました。私が実行している元のコマンドは複雑すぎてここで説明できないため、問題を示す例を作成しました (これらのコマンドはすべて基本的に何もしていないことがわかっています)。また、データが実際に入力から出力にコピーされているかどうかを示すために pv を使用しています。

cat /dev/zero | pv > /dev/null

これは期待どおりに機能します。(/dev/zero から /dev/null にデータをコピーします)

cat /dev/zero | tee /dev/null | pv > /dev/null

これも期待どおりに機能します (データを複製し、両方のコピーを /dev/null に送信します)。

cat /dev/zero | tee >(pv -c > /dev/null) | pv -c > /dev/null

このコマンドは部分的にしか機能しません。STDIN から STDOUT へのコピーは引き続き機能しますが (1 つの pv に短時間進行状況が表示されます)、コマンド全体が無名パイプによって停止されます。匿名パイプは何も受信せず、出力の 1 つに書き込むことができないため、t が停止します。 (/dev/null の代わりにファイルに書き込むようにして、これを確認しました)。

なぜこれが bash で機能しないのか (予想どおり?) を知っている人がいれば、喜んで助けてくれます。

PS: bash の代わりに zsh を使用すると、コマンドは期待どおりに実行されます。残念ながら、これを実行する必要があるシステムには zsh がなく、そのシステムに zsh を展開する方法がありません。

4

1 に答える 1

1

<( ... )プロセスの代替に使用する場合、内部で実行されているプロセスには制御端末がありません。ただしpv、その結果は常に端末に表示されます。何もない場合は停止します。

コードを実行し、実行中に を実行すると、次のps axfように表示されます。

23412 pts/16   S      0:00  \_ bash
24255 pts/16   S+     0:00      \_ cat /dev/zero
24256 pts/16   S+     0:00      \_ tee /dev/fd/63
24258 pts/16   S      0:00      |   \_ bash
24259 pts/16   T      0:00      |       \_ pv -c
24257 pts/16   S+     0:00      \_ pv -c

...これはpv -c、プロセス内で実行された置換 (2 番目の下のものbash) が停止T状態にあることを示しています。実行するために制御端末を待機しています。何もないため、永久に停止し、最終的にそのパイプへのデータの送信を停止します。bash

于 2015-11-19T12:39:22.137 に答える