標準出力と標準エラー出力をひとまとめにする記述について

command の標準出力と標準エラー出力をoutoputというファイルに出力するには以下のように記述します。

$ command > output 2>&1

なにをやってるのだこれは????となったのでまとめ。


まずは、ファイルディスクリプタについておさらい。

0 → 標準入力
1 → 標準出力
2 → 標準エラー出力


以上を踏まえて、冒頭のコマンドを分割して考えるとわかりやすい。
まず

$ command > output

$ command 1> output

は同じである。
ファイルディスクリプタを指定しなければリダイレクト先は1番、標準出力が指定される。
2番、標準エラー出力は指定されていないので端末の画面に垂れ流される。

$ command 2>&1

これは出力先を2番から1番のファイルディスクリプタに変更するという意味だ。
1番のリダイレクト先は端末の画面なので、標準出力と標準エラー出力が端末の画面に出力される。
2番の出力先も端末の画面なので、これ単体では特に意味はない。

まとめると

$ command > output 2>&1

で標準出力の出力先を指定してやり

$ command > output 2>&1

標準エラー出力の出力先を標準出力に指定している。

これによって標準出力も標準エラー出力もoutputに出力される。

ちなみに

$ command 2>&1 > output

ではうまくいかない。
これが理解できればもう悩むことはない。

[参考]
UNIXの部屋 コマンド検索:リダイレクト
入門UNIXシェルプログラミング

追記 2013-08-08

Bash Reference Manualを読んでると以下の記述があった。

This construct allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of word.

There are two formats for redirecting standard output and standard error:

&>word

and

>&word

Of the two forms, the first is preferred. This is semantically equivalent to

>word 2>&1

なんと、>word 2>&1 でも &>word でも >&word でも意味は同じでどれも標準出力と標準エラー出力がwordに出力されると。
そういえば&のあとに何も指定しなければ標準出力と標準エラー出力も出力されるって聞いたことがあったような。。。

じゃあ、これからは &>word で書くようにしよう。