1つのコマンドの出力を複数のコマンドにリダイレクトできますか?

1つのコマンドの出力を複数のコマンドにリダイレクトできますか?

私が知っている限り、teeコマンドを使用して標準出力を画面とは異なるファイルに分割できます。

command -option1 -option2 argument | tee file1 file2 file3 

理論的には、一連のコマンドを生成できるように、teeを使用して出力をファイルの代わりにコマンドにリダイレクトできますか?

答え1

名前付きパイプ(http://linux.die.net/man/1/mkfifo)コマンドラインからtee名前付きパイプのコマンドを読みます。

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

完了すると、command名前tee付きパイプが閉じられ、各パイプにEOF(ゼロバイト読み取り)信号が発生し、/tmp/dataN通常cmdNプロセスは終了します。実際の例:

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

バックグラウンドプロセスのため、シェルはプログラムが出力される前にプロンプ​​トを返します。 3 つのインスタンスはすべてwc正常に終了しました。

答え2

私が正しく理解したら、あなたは同等のものを探していますが、同じtee file1 file2 file3データを3つのファイルに書き込むのではなく、同じデータを3つのコマンドにパイプしたいと思います。file1file2file3cmd1cmd2cmd3

… | ??? cmd1 cmd2 cmd3

次のようにする必要があります。

… | cmd1 &
… | cmd2 &
… | cmd3 &

しかし、一度だけ実行されます。

これを行う方法は2つあります。

Ksh93、bash、zshのサポートプロセスの交換。これは、コマンドの引数がファイルになることを許可し、書き込み時にデータをコマンドへの入力に渡すパイプの一般化です(読み取り時にコマンドのデータ出力を取得する入力バリアントもあります)。 。それは、

echo hello | tee >(cmd1)

hello標準出力として印刷し、さらに入力としてcmd1実行しますhello

たとえば、入力をコピーしてandsomecommandに渡すには、次のようにします。cmd1cmd2

somecommand | tee >(cmd1) | cmd2

シェルがプロセス置換をサポートしていない場合は、名前付きパイプを使用できます。バラよりアルチェゴの答えどのように動作するかをご覧ください。名前付きパイプは、プロセスを作成して削除するだけでなく、プロセスを手動で開始して同期する必要があるため、プロセスの交換よりも便利ではありません。完全に移植可能であるという利点がありますが、すべてのシェルがプロセス置換をサポートしているわけではありません。プロセス交換以外のシナリオでも使用できます。

一部のシステムでは、プロセスの交換は内部で名前付きパイプを使用します。ただし、ほとんどのシステムでは次の点に依存しています。ファイル記述子を表す名前付きファイル

答え3

少なくともmkfifoプロセス置換を使用して、以下をスキップできます。

command -option1 -option2 argument | tee >(cmd1) >(cmd2) >(cmd3)

または採用アルケの例

tee >(wc -l) >(wc -w) >(wc -c) < /etc/passwd >/dev/null

答え4

pee誰もmoreutilsのコマンドに言及していないという事実に驚きました(https://joeyh.name/code/moreutils)。

関連情報