sh のリダイレクト
一度理解してもすぐに忘れて混乱するのでメモ。
$ command 2>&1 >hoge
このコマンドラインを実行すると command の標準出力(1)は hoge へ書かれ、command の標準エラー出力(2)は画面に出力される。
間違った理解をしている時は、頭の中では配管工事*1をイメージしている。
通常の配管は次のようになっている。
0──→0 1──→1 2──→2
以下のコマンドラインを実行すると、
$ command 2>&1 >hoge
2>&1 の部分で 2 から 1 へ配管工事が行われ
0──→0 1─┬→1 2─┘ 2
となり、次に >hoge の部分で
0──→0 1─┬→hoge 2─┘ 2
となるという誤った理解をしてしまう。
正しい理解は、駅のホームの番号と、電車の行き先というイメージ。
通常は、ホームの番号とそのホームに入ってくる電車の行き先は次のようになっている。
(ホームの番号:「電車の行き先」) 0:「キーボード」 1:「画面」 2:「画面」
以下のコマンドラインを実行すると、
$ command 2>&1 >hoge
2>&1 の部分で 2 番線の電車の行き先は、1 番線の電車の行き先と同じになる。
0:「キーボード」 1:「画面」 2:「画面」 ← 1 番線の電車の行き先と同じなる*2
次に >hoge の部分で 1 番線の電車の行き先を hoge に変更する*3。
0:「キーボード」 1:「hoge」 ← 行き先が変更される 2:「画面」
したがって、command の標準出力(1)は hoge へ書かれ、command の標準エラー出力(2)は画面に出力される。
上記のコマンドラインと似て非なる次のコマンドラインの場合、
$ command >hoge 2>&1
>hoge の部分で 1 番線の電車の行き先を hoge に変更する。
0:「キーボード」 1:「hoge」 ← 行き先が変更される 2:「画面」
2>&1 の部分で 2 番線の電車の行き先は、1 番線の電車の行き先と同じになる。
0:「キーボード」 1:「hoge」 2:「hoge」 ← 1 番線の電車の行き先と同じなる
したがって、command の標準出力(1)と標準エラー出力(2)はどちらも hoge へ書かれることになる。
ちゃんと調べてないが
- a>&b は dup2(b, a);
- c>filename は fd = open("filename"); dup2(fd, c);