bashを介していくつかの機能を実装するためにCentos 6でパイプを使用しています。これらのパイプラインではデータをログファイルにエクスポートしたいが、このデータはパイプラインの他のパイプから提供されるため、各ログ行の前にタグを挿入して区切りたいとします。より正確には、次のことをしたいと思います。
COMMAND1 | (create a line in the log file like: "command1: " + output of the command) | COMMAND2 ...
多くの研究の終わりに、私は次の視点に達しました。
COMMAND1 | tee >(ifne echo -n "command1: " >> out.log) | tee -a out.log | COMMAND2
これはうまくいきますが、問題があります。 2番目のファイルはtee
最初にファイルに書き込まれ、最初のファイルに書き込まれますtee
。だから私は次のようになります:
(output of command 1)
command1:
変える
command1: (output of command 1)
ifne
私は2番目が最初のtee
前に実行されるのに十分な遅延を持っていると思います。削除するとifne
うまくいきます。問題は、ifne
しばしばアイドル出力があり、それを記録したくないので、そうする必要があるということです。
2番目のティーが最初のティーが終わるのを待つ方法は?
答え1
私が正しく理解した場合は、COMMAND1から来たことを示すタグを使用してCOMMAND1の出力を記録しようとしています。 1つの方法は次のとおりです。
COMMAND1 | tee >(sed 's/^/command1: /' >>out.log) | COMMAND2
気づく:
- これにより、
command1:
最初の行だけでなく各行の先頭にタグが追加されます。これは望ましいと思いますが、望む作業ではありません。 command1
sed 特殊文字を含めないでください。それ以外の場合はバックスラッシュで保護する必要があります。- 追加用に開いているため、
out.log
同じログファイルに複数のコマンドを並列に出力しても、出力が重複する危険はありません。 out.log
このフラグメントでは一度だけ開くので、すべての行が順番に表示されます。悪いニュースは、同じファイルに複数回並列にログインした場合、その行が希望の順序で表示されるという保証がないことです。例えば、
echo hello | tee >(sed 's/^/command1: /' >>out.log) | tr a-z A-Z | tee >(sed 's/^/command2: /' >>out.log)
command2: HELLO
以前にログインしている可能性がありますcommand1: HELLO
。- 同じファイルに複数回並列にログインし、行が長すぎると、他のインスタンスの行が分散される可能性があります。一般的なsedの実装は、以下よりも通過しないと思います。
PIPE_BUF
バイト長ですが、わかりません。
順序と原子性の制限があるので、別のファイルに書き込むことをお勧めします。この場合、プレフィックスは必要ありません。