コマンドラインで出力リダイレクトに>
記号が使われていることは知っているのですが、コマンドラインで2>&1
記号が使われていることを説明しているものが見つからず困っています。例えば
curl http://www.google.com > /dev/null 2>&1 &
68 Matt Huggins 2009-11-16
1
は標準出力 (stdout) を示す。2
は標準エラー (stderr) を示す
つまり、2>&1
は標準出力がリダイレクトされているところに標準エラーを送るように言っているのです。これは /dev/null
に送られているので、出力を全く無視しているのと同じことになります
83 Chealion 2009-11-16
tl;dr
backgroundにあるhttp://www.google.com
を取得し、stdout
とstderr
の両方を破棄する
curl http://www.google.com > /dev/null 2>&1 &
と同じです
curl http://www.google.com > /dev/null 2>/dev/null &
Basics
0
、1
、2
は、POSIX オペレーティングシステムにおける標準ファイルディスクリプタを表しています。ファイルディスクリプタは、(基本的に) ファイルや ソケット へのシステム参照です
C言語で新しいファイル記述子を作成すると、次のようになります
fd = open("data.dat", O_RDONLY)
ほとんどのUnixシステムのコマンドは、何らかの入力を受けてその結果をターミナルに出力します。curl
は指定された url (google dot com) にあるものは何でも取得し、その結果を stdout
に表示します
Redirection
あなたが言ったように、<
と>
はコマンドからの出力をファイルのような別の場所にリダイレクトするために使われます
例えば、ls > myfiles.txt
では、ls
はカレントディレクトリの内容を取得し、>
はその出力をmyfiles.txt
にリダイレクトします(ファイルが存在しない場合は作成され、そうでなければ上書きされますが、代わりに>
の代わりに>>
を使ってファイルに追加することもできます)。上記のコマンドを実行すると、ターミナルに何も表示されないことに気づくでしょう。これは通常、Unix システムでは成功を意味します。これを確認するには、cat myfiles.txt
でファイルの内容を画面に表示します
> /dev/null 2>&1
最初の部分 > /dev/null
は stdout
、つまり curl
の出力を /dev/null
にリダイレクトし、2>&1
は stderr
を stdout
にリダイレクトします (これは /dev/null
にリダイレクトされたばかりなので、すべてが /dev/null
に送られることになります)
2>&1
の左側は何がリダイレクトされるかを示し、右側はどこにリダイレクトされるかを示します。&
はstdout (1)
やstderr (2)
と1
や2
という名前のファイルを区別するために右側で使われています。つまり、2>1
は、1
という名前の新しいファイルを(まだ存在していなければ)作成し、stderr
の結果をそこにダンプすることになります
/dev/null
は空のファイルであり、そこに書き込まれたものをすべて破棄するために使われる仕組みです。つまり、curl http://www.google.com > /dev/null
はcurl
の出力を効果的に抑制していることになります
しかし、ターミナルに表示されたままのものがあるのはなぜだろうか。これはcurl
の通常の出力ではなく、stderr
に送られたデータで、ここではエラーだけでなく進捗状況や診断情報を表示するために使われています
curl http://www.google.com > /dev/null 2>&1
はcurl
の出力とcurl
の進行情報の両方を無視します。その結果、端末には何も表示されません
Finally
最後の &
は、ジョブ として、バックグラウンド でコマンドを実行するようシェルに指示する方法です。これにより、プロンプトがすぐに戻り、コマンドは舞台裏で非同期的に実行されます。現在のジョブを見るには、ターミナルで jobs
と入力してください。これは システムで実行されているプロセスとは異なることに注意してくださいこれらのプロセスを見るには、ターミナルで top
と入力してください
References
31 Jorge Bucaran 2014-11-30
2
はSTDERRを参照します。2>&1
は1
(STDOUT)と同じ場所にSTDERRを送ります
5 John T 2009-11-16
以下のように理解しています
コマンドの出力情報とエラー情報を画面上で読みたいだけならば、ただ書けばいい。curl http://www.google.com
また、出力情報をターミナル画面ではなくファイルに保存して後で確認したい場合は、以下のように書きます。curl http://www.google.com > logfile
しかし、この方法では、>
はStdOutをlogfile
にリダイレクトするだけなので、StdErrの情報は省略されます
そのため、一度実行に失敗したコマンドのエラー情報を気にするのであれば、2>&1
でStdOutとStdErrを組み合わせる必要があります(つまり、StdErrをStdOutに畳み込む)ので、以下のようなコマンドラインを書くことができます。curl http://www.google.com > logfile
2>&1
0 YaOzI 2013-12-06