次の2つのコマンドの違いを知りたかった
2>&1 > output.log
そして
2>&1 | tee output.log
同僚の1人が2番目のオプションを使用してリダイレクトするのを見ました。私は2>&1が何をするか知っています、私の唯一の質問は、単純なリダイレクト「>」演算子を使用できるteeを使用する目的は何ですか?
次の2つのコマンドの違いを知りたかった
2>&1 > output.log
そして
2>&1 | tee output.log
同僚の1人が2番目のオプションを使用してリダイレクトするのを見ました。私は2>&1が何をするか知っています、私の唯一の質問は、単純なリダイレクト「>」演算子を使用できるteeを使用する目的は何ですか?
回答:
2つのコマンドを別々に見る:
utility 2>&1 >output.log
ここで、リダイレクトは左から右の方法で処理されるため、標準エラーストリームは最初に標準出力ストリームの場所(場合によってはコンソール)にリダイレクトされ、次に標準出力ストリームがファイルにリダイレクトされます。標準エラーストリームはそのファイルにリダイレクトされません。
これの目に見える効果は、画面上の標準エラーで生成されたものと、ファイルの標準出力で生成されたものを取得することです。
utility 2>&1 | tee output.log
ここでは、標準エラーを標準出力ストリームと同じ場所にリダイレクトします。これは、両方のストリームがtee
単一の混在出力ストリームとしてユーティリティにパイプされ、この標準出力データがによって指定されたファイルに保存されることを意味しますtee
。さらに、データはtee
コンソールで再現されます(これはtee
、データストリームを複製するためです)。
どちらを使用するかは、何を達成したいかによって異なります。
2番目のパイプラインの効果を>
(のようにutility >output.log 2>&1
、標準出力とエラーの両方をファイルに保存するように)だけでは再現できないことに注意してください。tee
コンソールと出力ファイルのデータを取得するために使用する必要があります。
その他の注意事項:
最初のコマンドの目に見える効果、
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
、パイプラインの一部は何も取得しません標準入力で読み取ります。
utility 2>&1 > output.log | more_stuff
とutility >ouput.log
| more_stuff , is the difference that
more_stuff`には、コンソールへの入力として標準エラー出力がありますmore_stuff
か?2番目の例では、コンソールへの出力がないため、more_stuff
?への入力は本質的にありません。もしそうなら、標準出力がファイルに行き、標準エラーがコンソールに行くことに注意してください。
more_stuff
は、最初にエラーストリームにutility
送信されたもの(ただし、標準出力にリダイレクトされたもの)を受信します。存在しないとコンソールに表示されるためでmore_stuff
はなく、標準出力ストリームに送信されるためです。2番目のコマンドでmore_stuff
は、パイプラインの左側からの標準出力がないため、何も受け取りません。からのエラーストリームutility
は、2番目のコマンドで引き続きコンソールに表示されます。
utility > output.log | more_stuff
は、標準エラーの観点から標準出力ストリームに出力しないため、ということですか?
この回答 — derobert に関するコメントを必ずお読みください。
元の答え
2>&1 >output.log
は、最初にすべてのファイルハンドル2(標準エラー)をファイルハンドル1(標準出力)に送信し、それをfileに送信することを意味しますoutput.log
。つまり、標準エラーと標準出力をログファイルに送信します。
2>&1 | tee output.log
2>&1
ビットと同じで、標準出力と標準エラーを標準出力ストリームに結合します。次に、tee
プログラムを介してそれをパイプ処理し、標準入力(などcat
)とファイルにも標準入力を送信します。そのため、2つのストリーム(エラーと出力)を結合し、それを端末とファイルに出力します。
一番下の行は、最初のファイルがstderr
/ stdout
をファイルに送信し、2番目のファイルがファイルと標準出力の両方に送信します(標準出力をリダイレクトする別の構造内にいる場合を除き、おそらく端末です)。
次のようなものを持つことができるので、最後の可能性に言及します。
(echo hello | tee xyzzy.txt) >plugh.txt
ターミナルには何もありません。
cat /doesnotexist 2>&1 >output.txt
- cat: /doesnotexist: No such file or directory
端末にディスプレイが表示され、output.txtが空のファイルになります。優先順位とクロージャの2>&1
順序は、(現在の fd1 からdd fd2 )、次に>output.txt
(fd1をoutput.txtにリダイレクトし、他は何も変更しない)です。2>&1 |
異なる理由は、優先順位:|
beforeによるもの>
です。
最初のコマンドは別のタスクを実行します。
後
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番目は、ファイルと画面の両方に出力します。
最初にいくつかのサンプルコードを見てみましょう。
#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)メッセージがあり、コンソールに出力される場合
Unix出力ストリームを要約した投稿は次のとおりです。http://www.devcodenote.com/2015/04/unix-output-streams.html
投稿からの抜粋:
3つの標準出力ストリームがあります。
STDIN - Standard Input - Writes from an input device to the program
STDOUT - Standard Output - Writes program output to screen unless specified otherwise.
STDERR - Standard Error Output - Writes error messages. Also printed to the screen unless specified otherwise.
utility 2>&1 | tee output.log
ファイルに書き込まれて、あなたは1以来2も同様で、ティーに向けられていると言うことは意味しています。ティーは、ストリームを複製しているので、出力は両方?だけでなく、コンソール上に表示される間そこで違いutility 2>&1 > output.log
とutility 2>&1 | tee output.log
でtee
、それは、ストリームを複製することを正しいだろうということ。?