bashで標準入出力,標準エラー出力をリダイレクトするときのお話.
よくふわっと使っていた2>&1
とかの&の意味とか知りたくてちょっと調べました.
##リダイレクトとは
コマンド実行前に,コマンドの入出力を置き換えできる.また,シェルの実行環境に対してファイルをオープン,クローズできたりする.
基本的にリダイレクトは左から右に評価される.
###入力のリダイレクト
[n]<file
fileがオープンされて,ファイルディスクリプタnに読み込まれる.
nが指定されていないと標準入力(ファイルディスクリプタ0)に読み込む.
###出力のリダイレクト
[n]>file
fileがオープンされて,ファイルディスクリプタnに読み込まれる.
nが指定されていないと標準出力(ファイルディスクリプタ1)に読み込む.
fileが存在しない場合は作成される.fileが指定されてないとシンタックスエラー.
ちなみに[n]>>file
こうすると追記になる.
###ファイルディスクリプタの複製(Duplicate)
[n]<&word
こうすると,入力ディスクリプタの複製を行なう.wordが1桁以上の数値に展開されるとnはそのディスクリプタのコピーとなる.wordが入力のために開かれたファイルディスクリプタを指していない場合はエラーとなる.
nが特に指定されなかった場合,標準入力(0)に複製される.fileに-
が指定された場合,ファイルディスクリプタnはクローズされる.
[n]>&word
こちらでは出力ディスクリプタの複製を行なう.エラーとかは入力ディスクリプタの複製と同様.
nが特に指定されなかった場合,標準出力(1)に複製される.
nが指定されず,かつwordが1桁以上の数値に展開できなかった場合,標準出力と標準エラー出力がword(ファイル)にリダイレクトされる.
##動作確認
以上のことを踏まえて、以下の様なプログラムで動作を確認してみる.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
fprintf(stdout, "stdout!\n");
fprintf(stderr, "stderr!\n");
exit(0);
}
$ ./a.out
stdout!
stderr!
//デフォルトで標準エラー出力は標準出力にリダイレクトされている.
$ ./a.out > hoge 2>&1
$ cat hoge
stderr!
stdout!
//左から評価される.(1)標準出力はhogeにリダイレクト (2)標準エラー出力には標準出力のファイルディスクリプタ(=hogeへの書き込み)をコピー
$ ./a.out 2>&1 > huga
stderr!
$ cat huga
stdout!
//左から評価される.(1)標準エラー出力には標準出力のファイルディスクリプタ(=画面に表示)をコピー (2)標準出力はfugaにリダイレクト
$ ./a.out > piyo
stderr!
$ cat piyo
stdout!
//何も指定していないので標準出力だけがpiyoにリダイレクトされる
$ ./a.out >&hogehoge
$ cat hogehoge
stderr!
stdout!
//標準出力と標準エラー出力を両方hogehogeにリダイレクト.>&とhogehogeの間にスペースがあってもいい
おわり
##参考
$ man bash