このコマンドは何をしますか?
exec 2>&1
技術的に言えば、stderr を stdout に複製またはコピーします。
通常、これを実行するために exec は必要ありません。ファイル記述子での exec のより典型的な使用法は、未使用のファイル記述子にファイルを割り当てたいことを示すことです。
exec 35< my_input
ところで、ファイルにパイプするときの宣言の順序が重要であることを忘れないでください。
ls > mydirlist 2>&1
コマンドは、stdout と stderr の両方をファイル mydirlist に送信するため、機能します。
ls 2>&1 > mydirlist
stdout が mydirlist にリダイレクトされる前に stderr が stdout のコピーを作成したため、stderr ではなく stdout のみをファイル mydirlist に送信します。
編集:これは、シェルが左から右にスキャンする方法です。したがって、「stdout を mydirlist に送信する」と言う前に、「stderr を stdout にコピーする」と言うように 2 番目のものを読んでください。次に、最初のものを「stdoutをファイルmydirlistに送信する」と読んでから、「設定したstdoutにstderrを複製します」と読みます。知っている。それはまったく直感的ではありません!
「2>&1」が何をするかについて私が見たより良い記事の1つは、Bash One-Liners Explained、パートIII:リダイレクトに関するすべてです。
しかし、この質問に対する現在の回答が提供できないのは、単純な「実行」の後にこれを実行したい理由です。execコマンドのbashmanページで説明されているように、「コマンドが指定されていない場合、リダイレクトは現在のシェルで有効になります」。
out-and-err.py
stdoutに出力行を書き込み、stderrに別の行を書き込むという簡単なスクリプトを作成しました。
#!/usr/bin/python
import sys
sys.stdout.write('this is stdout.\n')
sys.stderr.write('this is stderr.\n')
そして、それをout-and-err.shというシェルスクリプトで「exec2>&1」でラップしました。
#!/bin/bash
exec 2>&1
./out-and-err.py
Pythonスクリプトだけを実行すると、stdoutとstderrは別々になります。
$ ./out-and-err.py 1> out 2> err
$ cat out
this is stdout.
$ cat err
the is stderr.
しかし、シェルスクリプトを実行すると、次の後にexecがすべてのstderrを処理することがわかります。
$ ./out-and-err.sh 1> out 2> err
$ cat out
this is stdout.
this is stderr.
$ cat err
$
ラッピングシェルスクリプトが1つのpythonコマンドだけでなく、すべての出力をstdoutに結合する必要がある場合は、「exec 2>&1」を実行すると簡単になります。
標準エラーを標準出力に結び付けます
これ2
はstderrであり、1
stdoutです。プログラムを実行すると、通常の出力が stdout に表示されますが、エラーや警告は通常 stderr に送られます。たとえば、すべての出力をファイルにパイプする場合は、最初に stderr と stdout を2>&1
.
@cmaが言ったように、stderrをstdoutに置きます。この動作が必要な理由は、grep またはその他のユーティリティを使用して、stderr にのみ表示される出力をキャプチャするためです。または、後で処理するために、stderr を含むすべての出力をファイルに保存することもできます。
私が遭遇した非常に便利なアプリケーションの 1 つexec 2>&1
は、マージしたい場合stderr
やstdout
、セミコロンで区切られた複数のコマンドを使用する場合です。私の特定の例は、PHP で複数のコマンドを送信してpopen
いて、シェル プロンプトでコマンドを入力した場合に表示されるように、インターリーブされたエラーを確認したかったときに発生しました。
$ echo hi ; yikes ; echo there
hi
-bash: yikes: command not found
there
$
以下はマージされず、最後stderr
をstdout
除いて(エラーが発生するecho
ため無意味です):yikes
echo hi ; yikes ; echo there 2>&1
次のように、マージされた出力を「難しい方法」で取得できます。
echo hi 2>&1; yikes 2>&1; echo there 2>&1
を使用すると、見た目がすっきりし、エラーが発生しにくくなりますexec
。
exec 2>&1 ; echo hi; echo yikes; echo there
セミコロンで区切られた 3 つのコマンドを実行した場合、端末で表示されるのとまったく同じように、stdout
とstderr
出力が適切にインターリーブされます。