web-dev-qa-db-ja.com

出力を2>&1と1>&2にリダイレクトするのはなぜですか?

私は2>&11>&2を使用するいくつかのコマンドに出会いましたが、それを使用する目的と使用すべき時期については頭に入れません。

私が理解していること

1は標準出力を表し、2は標準エラーを表します。私は、2>&12の出力を1に、またはその逆に結合することを理解しています。

得られないもの

  1. いつ使うべきですか?
  2. それはどんな目的に役立ちますか?
33
PeanutsMonkey

時には、stdoutstderrの両方を同じ場所にリダイレクトしたいことがあります。これは>&が使用されている場合です。


たとえば、stdoutとstderrの両方を同じファイルに書き込む場合(/dev/nullまたはoutput.txt)、それらを別々にリダイレクトすることができます。

app 1>/dev/null 2>/dev/null

あるいは、一方のファイルディスクリプタをファイルにリダイレクトし、もう一方のファイルディスクリプタを最初のファイルディスクリプタにリダイレクトすることもできます。

app 1>/dev/null 2>&1

app 2>/dev/null 1>&2

最初の例では、2>&1は、ファイル記述子#2を、#1がすでに指している場所にポイントしています。 2番目の例は、stderrから始めて同じことを実現しています。

別の例として、stdout(ファイルディスクリプタ#1)がすでに目的の場所を指している場合がありますが、名前で参照することはできません(パイプ、ソケットなどに関連付けられている可能性があります)。これは、プロセス拡張(` `または$( )演算子)を使用している場合によく発生します。通常、これは標準出力のみを取り込みますが、その中に標準エラーを含めることをお勧めします。この場合、stderrをstdoutに指すために>&も使用します。

out=$(app 2>&1)

もう1つの一般的な例は、ページャー、grep、または類似のユーティリティです。パイプ|は通常stdoutに対してのみ機能するため、パイプを使用する前にstderrをstdoutにリダイレクトします。

app 2>&1 | grep hello

2>&11>&2のどちらが正しいのかを知る方法は? すでに設定されているファイル記述子は>&の右側に移動し、リダイレクトしたいファイル記述子は左側に移動します。 (2>&1は「ファイルディスクリプタ#2からファイルディスクリプタ#1を指す」を意味します。)


一部のシェルには、一般的なリダイレクトへのショートカットがあります。これがBashの例です。

  • 1>>に短縮することができます

  • 1>foo 2>&1から>&fooまたは&>foo

  • 2>&1 | programから|& program

36
grawity

stdout1)とstderr2)の両方を同じ場所(例えば/dev/null)にリダイレクトしたいことがあります。これを実現する1つの方法は次のとおりです。

$ program 1>/dev/null 2>/dev/null

しかし、ほとんどの人はこれをstderr2>&1stdoutにリダイレクトすることで短縮します。

$ program 1>/dev/null 2>&1

さらに短いバージョンは以下のとおりです。

$ program >&- 2>&-
2
Zaz

必要なときの状況の1つは、straceの出力をページャに表示したいときです。 straceはその出力を標準エラーに出力し、パイプは一般的に標準出力を標準入力なので、リダイレクトを使用する必要があります。

strace -p $pid 2>&1 | less
2
jpalecek

2:それはあなたが標準エラーと標準出力の両方から来る出力を持つことになる時のためであり、そしてあなたはそれらを単一の文字列に組み立てたいです。

1:標準エラーと標準出力の両方の出力を操作したいとき。

1
soandos

Stderrをstdoutにリダイレクトする場合はすでにここで説明されています(例えば(grep)エラーメッセージをフィルタリングするためにそれを使用します)。

もう1つのケースは、stdoutをstderrにリダイレクトすることです。 (少なくとも私にとっては)一般的な使用例は、(私のシェルスクリプトでは) "echo"を付けて印刷された警告/エラーメッセージをstderrに送信することです(そうすればユーザーの注意を引くことができます)。

例えば、

echo "file \"${file\" does not exist..." 1>&2
0
umläute

代替シナリオ:端末コマンドは別の端末に出力を表示

それらを識別するために各端末でttyコマンドを使用します。

$ tty
/dev/pts/0

$ tty
/dev/pts/1

これらのTTYを想定して、最初の端末の標準出力を2番目の端末にリダイレクトするには、最初の端末でこれを実行します。

exec 1>/dev/pts/1

注:これですべてのコマンド出力がpts/1に表示されます。

Pts/0のデフォルトの動作標準出力を復元するには、次のようにします。

exec 1>/dev/pts/0

デモンストレーションについては このビデオ をご覧ください。

0

私はそれを使って独立したジョブを開始します。

someProgram 2>&1 >& my.log &

それから私はログアウトすることができ、someProgramはまだ実行されます。この機能はGNU Screen、tmux、その他のプログラムによって提供されています - しかし、ここでは外部の依存関係なしに実現されています。

0
Adobe

これら3つのファイルがあるtryという名前のディレクトリがあるとします。file file1 and file2.

今このコマンドを実行します。

cat file file1 file2 file3

最初の3つのファイルは開きますが、catは4番目のファイルを開くときにエラーが発生します。ファイルは存在しないためです。

今すぐ実行します。

cat file file1 file2 file3 1>outfile 2>&1

画面には何も出力されません。最初に1>outfileはコマンドの出力をoutfileにリダイレクトし、次に2>&1を開こうとしているときにスローされたエラーをoutfileにリダイレクトします(file3)。

1>&2も同様に機能し、エラーストリームを標準出力にリダイレクトします。

お役に立てれば!

0
Faiz