geek.conf.2

あるエンジニアの備忘録

標準入力/出力、標準エラーとかパイプとかteeとかさ〜 2>&1 | tee log

#bashのお話でお聞きください。
標準入力/出力とか標準エラーとかのお話。こいつら意味わかんねってことで私なりにまとめてみる。

正直言って以下の意味の詳細分かってませんでした。サーセン

#make install 2>&1 | tee make-install.log

○まずは能書きから2とか1とか何よ?なお話

LinuxてかUnixのOSでは通常、0から順番に整数値であるファイルディスクリプタ(ファイル識別子)が定義され、ファイルに与えてファイルを操作する。まあOSが割り当てるステータスコードのようなもの。中でも

0:標準入力(stdin)
1:標準出力(stdout)
2:標準エラー出力(stderr)
3:以降はOSが開くファイルに割り当てられる。

上記0,1,2はOS(シェル)が最初に用意するため、プログラムがファイルをオープンすると「3」から順番にディスクリプタが割り当てられる。

○今度は>&について

>&とは前者の出力先を後者の出力先と同じところとする、という意味

#make install 1>1make-install.log 2>2make-install.log

ではファイルディスクリプタ1を1make-install.logに、2を2make-install.logにリダイレクトするとなるが、
ファイルディスクリプタ1も2も1ファイルにリダイレクトしたいときには

#make install > make-install.log 2>&1

とする。

ここでファイルディスクリプタ1,2の出力先は通常はコンソール上である。
よく混乱してしまう書き方が

#make install 2>&1 > make-install.log

としてファイルディスクリプタ1,2をmake-install.logにリダイレクトしようとしてしまうが、間違いだ。

これだとmake installのファイルディスクリプタ1,2はコンソール上に出力されることは変わらず、make installの標準出力だけがmake-install.logに出力される。

リダイレクト>はコマンドの標準出力結果だけしかリダイレクトされないことに注意。

○次にパイプ|について

パイプ|は前者のコマンドの標準出力を後者のコマンドに渡すことを意味する。これで十分だろう。

○最後にteeコマンドについて

teeはパイプ|で渡した標準出力をコンソール上にも出力したい場合に用いる。

○おさらい

#make install 2>&1 | tee make-install.log

はmake installの標準エラー出力を同様の標準出力先を同じ出力先にしてパイプ|以降のmake-install.logに渡し、teeコマンドによってコンソールにもパイプ|以降に渡した出力を出力する。


呪文を翻訳したぜ!