私の知る限り、teeコマンドを使用して、標準出力を画面とその他のファイルに分割できます。
command -option1 -option2 argument | tee file1 file2 file3
Teeを使用してファイルではなくコマンドに出力をリダイレクトして、理論的にコマンドのチェーンを作成することは可能ですか?
tee
のコマンドラインで名前付きパイプ( http://linux.die.net/man/1/mkfifo )を使用して、名前付きパイプでコマンドを読み取ることができます。
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
は名前付きパイプを閉じます。これにより、各/tmp/dataN
でEOF(0バイトの読み取り))が通知されます通常は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
バックグラウンドプロセスのため、シェルはプログラム出力の前にプロンプトを返しました。 wc
の3つのインスタンスはすべて正常に終了しました。
私が正しく理解していれば、tee file1 file2 file3
に相当するものを探していますが、同じデータを3つのファイルfile1
、file2
およびfile3
に書き込むのではなく、同じデータを3つのコマンドcmd1
、cmd2
およびcmd3
にパイプします。つまり、.
… | ??? cmd1 cmd2 cmd3
同等である必要があります
… | cmd1 &
… | cmd2 &
… | cmd3 &
ただし、…
は1回だけ実行されます。
それには2つの方法があります。
Ksh93、bash、およびzshは プロセス置換 をサポートします。これは、コマンドの引数を、書き込み時にコマンドへの入力としてデータを渡すファイルにすることを可能にするパイプの一般化です(読み込まれると、コマンドによってデータ出力を取得する入力バリアントもあります)。 。あれは、
echo hello | tee >(cmd1)
hello
を標準出力に出力し、さらにhello
を入力としてcmd1
を実行します。
たとえば、somecommand
の入力を複製してcmd1
とcmd2
の両方に渡す場合は、次のように使用できます。
somecommand | tee >(cmd1) | cmd2
シェルがプロセス置換をサポートしていない場合は、代わりに名前付きパイプを使用できます。それがどのように機能するかについては Arcege's answer を参照してください。名前付きパイプは、作成して削除し、プロセスを手動で開始および同期する必要があるため、プロセス置換よりも便利ではありません。すべてのシェルがプロセスの置換をサポートしているわけではないのに、完全に移植可能であるという利点があります。これらは、プロセス置換が対象とするシナリオ以外のシナリオでも使用できます。
内部では、一部のシステムでは、プロセス置換は内部で名前付きパイプを使用します。ただし、ほとんどのシステムでは ファイル記述子を表す名前付きファイル に依存しています。
Moreutils( https://joeyh.name/code/moreutils )のpee
コマンドについてだれも言及していないことに驚いています。