読者です 読者をやめる 読者になる 読者になる

標準出力と標準エラーについて

標準入力は 0 番
標準出力は 1 番
標準エラー出力は 2 番

% command > file

「標準出力」をファイル file へ上書き。

% commnad >| file

「標準出力」をファイル file へ強制上書き。

% command 2> file

標準エラー出力」をファイル file へ上書き。

% command &> file

「標準出力」と「標準エラー出力」をfileへ 。

% command >> file

「標準出力」をファイル file に切り替える。ファイルへ追加。

% command > fileA 2> fileB

「標準出力」をファイル fileA へ。「標準エラー出力」をファイル fileB へ。

% command > fileA 2>&1

「標準出力」と「標準エラー出力」を同じファイル fileA へ。

% command1 | command2

「command1」の結果を「command2」へ渡す

% command1 |& command2

標準出力と標準エラー出力を両方リダイレクト

% ( command > file1 ) >& file2

標準出力を file1 に、標準エラー出力を file2 に

% command >/dev/null 2>&1

標準出力と標準エラーを/dev/nullへ

難しい話

参照URL:UNIXの部屋

標準エラー出力のみをパイプに出力する。
% command 2>&1 >/dev/null | command2
標準エラー出力のみをパイプに (出力を閉じるので、command が出力結果をチェックしているならエラーになる)。
% command 2>&1 >&- | command2
標準出力と標準エラー出力を交換する。
% command 3>&1 1>&2 2>&3
標準出力を捨て、標準エラー出力をページャで参照する。
% command 3>&1 >/dev/null 2>&3 | less

さて、先にも述べたように、標準出力と標準エラー出力をファイルに出力する場合は、
% command 1>file 2>&1
% command >file 2>&1 (1 を省略してもよい)
とする。しかし
% command 2>&1 1>file
% command 2>&1 >file (1 を省略してもよい)
は誤りである。なぜ上の書き方が正しいのか、なぜ下の書き方ではダメなのか説明できるだろうか。なお、「リダイレクトは右に書いたものから順に評価されるから」は間違いである。

そもそも「2>&1」という書き方は「2 の出力先を 1 にマージする」というイメージで捉えている人が多いのではないだろうか。「2>&1」の本当の意味は「2 の出力先を、1 の出力先と同じものに設定する」である。

まず、リダイレクトを指定しない場合は、
% command
⇒ 1 の出力先 … 画面
⇒ 2 の出力先 … 画面
となっている。標準出力のみをファイルにリダイレクトする場合は
% command 1>file
⇒ 1 の出力先 … file
⇒ 2 の出力先 … 画面
となる。では標準出力と標準エラー出力をファイル file に出力する
% command 1>file 2>&1
だが、これはまず「1>file」が処理されて、
⇒ 1 の出力先 … file
⇒ 2 の出力先 … 画面
となり、その後に「2>&1」が処理されて、
⇒ 1 の出力先 … file
⇒ 2 の出力先 … file (なぜなら「2 の出力先を、1 の出力先と同じものに設定した」から)
となって、めでたく標準出力と標準エラー出力が file に出力される。

一方、誤った書き方の
% command 2>&1 1>file
であるが、リダイレクト解析前の初期状態は
⇒ 1 の出力先 … 画面
⇒ 2 の出力先 … 画面
となっている。ここでシェルが「2>&1」を処理しても、
⇒ 1 の出力先 … 画面
⇒ 2 の出力先 … 画面
と何も変化しない。なぜなら、「2 の出力先を、1 の出力先と同じものに設定した」からである。その後に「1>file」が処理され、
⇒ 1 の出力先 … file
⇒ 2 の出力先 … 画面
となり、あなたの望んだものとは異なる結果となってしまう。