web-dev-qa-db-ja.com

2>&1> output.logと2>&1の違い| tee output.log

次の2つのコマンドの違いを知りたい

2>&1 > output.log 

そして

2>&1 | tee output.log

同僚の1人が2番目のオプションを使用してリダイレクトするのを見ました。 2>&1の機能を知っていますが、私の唯一の質問は、単純なリダイレクト ">"演算子を使用できるTを使用する目的は何ですか?

36

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部分です標準入力では何も読み取れません。

15
Kusalananda

編集メモ

この回答のコメントを必ずお読みくださいderobert


元の答え

2>&1 >output.logは、最初にすべてのファイルハンドル2のもの(標準エラー)をファイルハンドル1(標準出力)に送信することを意味します、次にそれをファイルoutput.logに送信します。つまり、標準エラーと標準出力をログファイルに送信します。

2>&1 | tee output.log2>&1ビットと同じで、標準出力と標準エラーを組み合わせて標準出力ストリームに出力します。次に、teeプログラムを介してその標準入力を標準出力(catなど)に送信し、alsoをファイルに送信します。したがって、2つのストリーム(エラーと出力)を結合し、それをターミナルとファイルに出力します。

一番下の行は、最初のファイルがstderr/stdoutをファイルに送信し、2番目のファイルがそれをbothファイルと標準出力(これはおそらくターミナルです(標準出力をリダイレクトしている別の構成内にいる場合を除きます)。

私はあなたが次のようなものを持つことができるので、最後の可能性について言及します

(echo hello | tee xyzzy.txt) >plugh.txt

端末には何もないところ。

24
user14408

最初のコマンドは別のタスクを実行します:

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の両方がファイルにリダイレクトされます。

8
osgx

前者はファイルにのみ出力します。 2番目の例では、両方をファイルに出力しますandを画面に出力します。

4
André Caron

の理由 2>&1 | teeは、stdoutとstderrの両方をログファイルにキャプチャして、同時に画面に表示できるようにします。これは>output.txt 2>&1 & tail -fも同様ですが、バックグラウンドで実行されたコマンドがいつ終了したかはわかりません。プログラムが終了したか、出力なしで実行されているかです。 2>&1 | teeは、プログラマにとって一般的なイディオムでした。

4
Arcege

最初にサンプルコードを見てみましょう:

#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)メッセージが必要な場合コンソールに出力

0
Hari Perev