2016/10/18 21:03:24

標準出力と標準エラー出力を闇に葬る

bash
目次(クリックするとジャンプします)
  • 1:出力を出したくない
  • 1.1:特別なデバイス
  • 1.2:標準出力を闇に葬る
  • 1.3:標準エラー出力を闇に葬る
  • 1.3.1:ファイルディスクリプタ
  • 1.4:確認
  • 2:後記

出力を出したくない

特別なデバイス

Unix系OSにはぬるぬるした闇が存在しています。

/dev/null/

これは擬似デバイス(pseudo-device)、またはスペシャルファイルなどと呼ばれます。

/dev/null/「ありとあらゆる入力を受け付けるが出力しない」という機能を持っています。

シェルスクリプトを書いている時に、出力されて欲しくない場合もありますよね。

そんな時にはこの/dev/null/を使うと出力を闇に葬り去ることができます。

標準出力を闇に葬る

以下のようなコマンド(全く訳に立たないコマンドですが)を例に見て行きます。

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

lsはご存知の通り、リストコマンドです。例では/dev/null/にリダイレクトをしています。 つまりこの時点で、lsの標準出力は/dev/null/に向かっているということになります。

コマンド > /dev/null/

で標準出力は闇に葬られますが、エラーが出た場合は標準エラー出力として出力されます。この挙動が好ましくない場合は標準エラー出力も闇に葬る必要があります。

この状態でも標準出力は出力されません。

$ ls > /dev/null/ 
$

しかし意図的にエラーを出してみると、標準エラー出力は出力されます。

$ ls > /dev/null /notexit
ls: /notexit にアクセスできません: そのようなファイルやディレクトリはありません

標準エラー出力を闇に葬る

さて標準エラー出力は以下の様にして葬っています。

2>&1

この意味を紐解いていきたいと思います。

ファイルディスクリプタ

Unix系のOSではファイルディスクリプタという仕組みでファイルや標準入出力を識別しています。

  • 標準出力はファイルディスクリプタ1
  • 標準エラー出力はファイルディスクリプタ2

に割り当てられています。

つまり先ほどの2>&1

標準エラー出力>&標準出力

という意味になります。

>&

左辺を右辺のファイルディスクリプタに送るという意味になりますので、2>&1は結局のところ

標準エラー出力を標準出力に送る

という意味になります。

そのために、標準エラー出力の出力先を標準出力に上書きしているのです。

コマンドは左から評価されますので、コマンド > /dev/null/の時点でこのコマンドの標準出力先は/dev/null/を指しています。

そこに2>&1を持ってきているので、結果的に

標準エラー出力>/dev/null/

と同じようなことになります。

確認

もう一度全体を見渡すと

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

リストコマンドの標準出力を/dev/null/におくる。標準エラー出力も/dev/null/行きの標準出力経由で

と言ったような意味になります。

今までのことを踏まえて試してみると…

標準出力の場合…

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

意図的にエラーを出した場合…

$ ls > /dev/null /notexit 2>&1
$

どちらもなんの出力もされません。完全に闇に葬られています。アナザーディメンジョン!!

後記

なんでも/dev/null/のことをビットバケツと呼ぶそうです。このビットバケツは昔、まだパンチカードでデータ入力をしていた頃、パンチ穴のカスを溜めていたゴミ箱のことを指すそうです。

確かにビットのゴミ箱だ…。

Unix関係の用語って歴史があってユーモアがあっていろいろ面白いですね。