ログを残すときに command > log.txt 2>&1 という書き方をよく見かけます。
この末尾の 2>&1 が何をしているのか、最初は分かりにくいですよね。
私も駆け出しの頃は、意味を知らないままコピペで使っていました。
仕組みを押さえると、ログ収集も出力の消し方も一気に楽になります。
出力には「標準出力」と「標準エラー出力」の2種類がある
コマンドの出力は、実は2つの流れに分かれています。
ふつうの結果が流れる標準出力と、エラーが流れる標準エラー出力です。
この2つには、それぞれ番号(ファイルディスクリプタ)が割り当てられています。
標準出力が「1」、標準エラー出力が「2」、とまず番号で覚えましょう。
画面上では混ざって見えても、内部では別々の通り道を流れているのです。
# 存在するファイルと存在しないファイルをまとめて ls
$ ls a.txt nofile.txt
a.txt # 標準出力(1)に出る
ls: nofile.txt: No such file or directory # 標準エラー出力(2)に出る
リダイレクト記号の基本を押さえる
リダイレクトは、出力の行き先をファイルなどへ切り替える仕組みです。
まず基本の記号から見ていきます。
> は、標準出力をファイルに上書き保存します。
>> を使うと、標準出力を末尾に追記できます。
番号を付けた 2> は、標準エラー出力の保存に使います。
# 標準出力だけを out.log へ
command > out.log
# 標準エラー出力だけを err.log へ
command 2> err.log
2>&1 は「エラーを出力と同じ場所へ送る」
ここでようやく本題の 2>&1 です。
これは「2番のエラーを、1番の出力と同じ行き先へ送る」という意味になります。
後ろの &1 にある & は、「1はファイル名ではなくディスクリプタの1番だ」と示す記号です。
このアンパサンドを忘れると、「1」という名前のファイルへ書き込んでしまいます。
# 標準出力とエラーを両方 log.txt にまとめる
command > log.txt 2>&1
順序で結果が変わる落とし穴
2>&1 は、書く順番によって結果が変わります。
先に出力先を決めてから、エラーをそこへ合流させる、この順序が肝心です。
command > file 2>&1 なら、標準出力もエラーも file に入ります。
ところが command 2>&1 > file と逆に書くと、結果が変わってきます。
この場合は標準出力だけが file に入り、エラーは画面へ残ってしまいます。
2>&1 は、書いた時点での「1番の行き先」に2番を合わせるからです。
# OK: 両方 file に入る
command > file 2>&1
# NG: 標準出力だけ file、エラーは画面に残る
command 2>&1 > file
いらない出力は /dev/null へ捨てる
出力を一切残したくないときは、/dev/null へ送ります。
/dev/null は、書き込まれたデータをすべて捨てる特別なファイルです。
定番の > /dev/null 2>&1 は、通常の出力もエラーも全部まとめて捨てる書き方になります。
bash なら &> /dev/null と、さらに短く書くこともできます。
# cron でよく使う「何も出力しない」書き方
command > /dev/null 2>&1
最後に
2>&1 は、番号で管理された出力の行き先を付け替える操作でした。
標準出力が1、標準エラー出力が2、この2つを意識するだけで読み解けます。
ログ収集や cron のジョブで頻出するので、仕組みで覚えておくと応用が利きます。
より詳しい仕様は Redirections(Bash公式マニュアル) が参考になります。
以上です。









コメントを残す