シェル備忘録
・リダイレクトとパイプ
どちらも入出力の宛先を変更する機能である。異なるのは、リダイレクトの場合は宛先がファイルであり、パイプの場合はプログラムの入力である点。
評価順序は
- パイプの評価 -> リダイレクトの評価
- 左から右
基本的なルールはこれだけなので難しい事はなさそうなのだが、いきなり
command1 2>&1 >/dev/null | command2
なんてのを見て、これが何を意味してるか分かる人ってそうはいない気がする。少なくとも俺はしばらく悩んだ。(苦笑
上記の例が何をやってるかを理解するには、「リダイレクトもパイプも要はファイルディスクリプタの書き換えである」と考えるといい。
ファイルディスクリプタとは、OSがファイルを扱うために使用する識別子の事。ファイル識別子とも呼ばれる。ファイルディスクリプタには、識別子、ファイル名、ファイルサイズ、ファイルの物理的な場所、作成日時、更新日時といった情報が含まれている。
まず、初期状態ではcommand1、command2のファイルディスクリプタ(以下、fd)とその内容は次のようになっている。数字はfd。
command1 | 0 | stdin | command2 | 0 | stdin |
1 | stdout | 1 | stdout | ||
2 | stdout | 2 | stdout |
command1 | 0 | stdin | command2 | 0 | A |
1 | A | 1 | stdout | ||
2 | stdout | 2 | stdout |
command1 | 0 | stdin | command2 | 0 | A |
1 | A | 1 | stdout | ||
2 | A | 2 | stdout |
command1 | 0 | stdin | command2 | 0 | A |
1 | /dev/null | 1 | stdout | ||
2 | A | 2 | stdout |