次の2つのコマンドの違いを知りたい
2>&1 > output.log
そして
2>&1 | tee output.log
同僚の1人が2番目のオプションを使用してリダイレクトするのを見ました。 2>&1の機能を知っていますが、私の唯一の質問は、単純なリダイレクト ">"演算子を使用できるTを使用する目的は何ですか?
2つのコマンドを個別に見る:
utility 2>&1 >output.log
ここでは、リダイレクトは左から右に処理されるため、標準エラーストリームは、最初に標準出力ストリーム(おそらくコンソール)のどこにでもリダイレクトされ、次に標準出力ストリームがファイルにリダイレクトされます。標準エラーストリームはnotがそのファイルにリダイレクトされます。
これの目に見える効果は、画面の標準エラーで生成されたものとファイルの標準出力で生成されたものを取得することです。
utility 2>&1 | tee output.log
ここでは、標準エラーを標準出力ストリームと同じ場所にリダイレクトします。これは、両方ストリームが単一の混在出力ストリームとしてtee
ユーティリティにパイプ処理され、この標準出力データがtee
によって指定されたファイルに保存されることを意味します。データはさらに、コンソールのtee
によって再現されます(これはtee
が行うことであり、データストリームを複製します)。
どちらを使用するかは、達成したいことによって異なります。
>
だけでは2番目のパイプラインの効果を再現できないことに注意してください(utility >output.log 2>&1
のように、標準出力とエラーの両方を最初に標準出力をoutput.log
ファイルにリダイレクトし、次に標準エラーを標準出力は現在進行中です)。コンソールおよび出力ファイルでデータを取得するには、tee
を使用する必要があります。
その他の注意事項:
visible最初のコマンドの効果、
utility 2>&1 >output.log
と同じになります
utility >output.log
つまり、標準出力はファイルに送られ、標準エラーはコンソールに送られます。
上記の各コマンドの最後にさらに処理ステップを追加すると、大きな違いが生じます。
utility 2>&1 >output.log | more_stuff
utility >output.log | more_stuff
最初のパイプラインでは、more_stuff
は最初にutility
から標準エラーストリームであるものを標準入力データとして取得しますが、2番目のパイプラインでは、パイプを介して送信される結果の標準出力ストリームのみであり、パイプラインのmore_stuff
部分です標準入力では何も読み取れません。
この回答のコメントを必ずお読みください— derobert 。
元の答え
2>&1 >output.log
は、最初にすべてのファイルハンドル2のもの(標準エラー)をファイルハンドル1(標準出力)に送信することを意味します、次にそれをファイルoutput.log
に送信します。つまり、標準エラーと標準出力をログファイルに送信します。
2>&1 | tee output.log
は2>&1
ビットと同じで、標準出力と標準エラーを組み合わせて標準出力ストリームに出力します。次に、tee
プログラムを介してその標準入力を標準出力(cat
など)に送信し、alsoをファイルに送信します。したがって、2つのストリーム(エラーと出力)を結合し、それをターミナルとファイルに出力します。
一番下の行は、最初のファイルがstderr
/stdout
をファイルに送信し、2番目のファイルがそれをbothファイルと標準出力(これはおそらくターミナルです(標準出力をリダイレクトしている別の構成内にいる場合を除きます)。
私はあなたが次のようなものを持つことができるので、最後の可能性について言及します
(echo hello | tee xyzzy.txt) >plugh.txt
端末には何もないところ。
最初のコマンドは別のタスクを実行します:
後
2>&1 > output.log
古いSTDOUTはSTDERRに保存(コピー)され、次にSTDOUTがファイルにリダイレクトされます。
したがって、stdoutはファイルに移動し、stderrはコンソールに移動します。
そして
2>&1 | tee output.log
両方のストリームがT型にリダイレクトされます。 Teeは、入力をstdout(この場合はコンソール)とファイル(output.log
)。
そして、別の形式の最初があります:
> output.log 2>&1
これにより、STDOUTとSTDERRの両方がファイルにリダイレクトされます。
前者はファイルにのみ出力します。 2番目の例では、両方をファイルに出力しますandを画面に出力します。
の理由 2>&1 | tee
は、stdoutとstderrの両方をログファイルにキャプチャして、同時に画面に表示できるようにします。これは>output.txt 2>&1 & tail -f
も同様ですが、バックグラウンドで実行されたコマンドがいつ終了したかはわかりません。プログラムが終了したか、出力なしで実行されているかです。 2>&1 | tee
は、プログラマにとって一般的なイディオムでした。
最初にサンプルコードを見てみましょう:
#include <stdio.h>
main()
{
// message 1, on stdout (using printf)
printf("%s", "message 1, on stdout (using printf)\n");
// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");
// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}
結果を比較します:./helloerror
+ファイル:メッセージなし;コンソール:メッセージ1、2、3;
./helloerror >error.txt
+ファイル:メッセージ1,2;コンソール:メッセージ3;
./helloerror 2>&1 >error.txt
+ファイル:メッセージ1,2;コンソール:メッセージ3;
+ ./helloerror> error.txtと同じ
./helloerror >error.txt 2>&1
+ファイル:メッセージ3,1,2;コンソール:メッセージなし。
+順序3が最初、次に1、次に2であることに注意してください
./helloerror | tee error.txt 2>&1
+ファイル:メッセージ1,2;コンソール:メッセージ3,1,2;
+順序3が最初、次に1、次に2であることに注意してください
./helloerror 2>&1 | tee error.txt
+ファイル:メッセージ3,1,2;コンソール:メッセージ3,1,2;
使用するには:./helloerror >error.txt 2>&1
->すべての(stdout + stderr)メッセージをファイルに入れたいがコンソールに固定されていない
./helloerror 2>&1 | tee error.txt
->ファイルにすべての(stdout + stderr)メッセージが必要な場合コンソールに出力