web-dev-qa-db-ja.com

複数のコマンドの出力を1つのファイルにリダイレクトする方法

次の2つのコマンドを持つbashスクリプトがあります。

ssh Host tail -f /some/file | awk ..... > /some/file &

ssh Host tail -f /some/file | grep .... > /some/file &

両方のコマンドの出力を同じファイルに送信するにはどうすればよいですか。

20
user2864207

Ssh呼び出しの数を減らすことができることに注意してください:

{  ssh Host tail -f /some/file | 
     tee >(awk ...) >(grep ...) >/dev/null
} > /some/file &

例:

{ echo foobar | tee >(sed 's/foo/FOO/') >(sed 's/bar/BAR/') > /dev/null; } > outputfile
cat outputfile 
fooBAR
FOObar
17
glenn jackman

>>で 'append'を使用するか、中かっこを使用してI/Oリダイレクトを囲むか、または(場合によって)execを使用します。

ssh Host tail -f /some/file | awk ..... >  /some/file &
ssh Host tail -f /some/file | grep .... >> /some/file &

または:

{
ssh Host tail -f /some/file | awk ..... &
ssh Host tail -f /some/file | grep .... &
} > /some/file

または:

exec > /some/file
ssh Host tail -f /some/file | awk ..... &
ssh Host tail -f /some/file | grep .... &

execの後、スクリプトの標準出力は全体として/some/fileに送られます。私はこのテクニックをほとんど使用しません。通常、代わりに{ ...; }テクニックを使用します。

注:中括弧の表記には注意する必要があります。私が示したことはうまくいきます。それを1行にフラット化しようとすると、{をコマンドのように処理し(その後にスペースを続けるなど)、}をコマンドのように処理する必要があります。 }の前にコマンドターミネータが必要です—私は改行を使用しましたが、背景に&または;も機能します。

したがって:

{ command1;  command2;  } >/some/file
{ command1 & command2 & } >/some/file

また、1つのリモートファイルで2つのtail -f操作が実行されている理由、およびawkパワーをスーパーgrepとして処理しない理由についても触れていません。すべてを1つにまとめました— 2つのコマンドのI/Oを1つのファイルにリダイレクトする方法についての表面的な質問にのみ対処しました。

30

これに対する最良の答えは、おそらくssh .... | grep ...行を削除し、他のコマンドのawkスクリプトを変更して、grepコマンドから取得していた機能を追加することです。 ..

それはボーナスの副作用としてインターリーブ問題を取り除きます。

2
twalberg