[Shell] 標準出力と標準エラー出力
ターミナルなどでコマンドを実行すれば、そのターミナルの画面にコマンドの出力が表示される。 これは、そのコマンドの標準出力が、そのターミナルに紐付いているからだ。
コマンドの出力をファイルへ保存したいなら、シェルのリダイレクトという機能を使って、標準出力をファイルへ紐付ける。
$ COMMAND > file.txt
一方、コマンドのエラーメッセージは、標準エラー出力
へ送られるが、この標準エラー出力
もターミナルに紐付いている。変更するには2>
を使う。
$ COMMAND 2> error.txt
この2
という番号はファイルディスクリプタ(File Descriptor)と呼ばれる。 標準出力が1、標準エラー出力が2というのが決っているようだ。指定しなければ、1がデフォルトになる。
標準出力と標準エラー出力の両方を変更するなら、次のように書く。
$ COMMAND 2> error.txt 1> file.txt
ファイルディスクリプタの1は書かなくても同じなので、これでいい。
$ COMMAND 2> error.txt > file.txt
標準エラー出力を標準出力と同じに紐付けるなら、&
を使う。
$ COMMAND 2>&1
標準出力1と標準エラー出力2を同じファイルへ紐付ける。
$ COMMAND 1>file.txt 2>&1
次のように順番が逆だとうまく動かない。
$ COMMAND 2>&1 1>file.txt # 悪い例
なぜなら、最初に2>&1
を指定しても この時点では標準出力はターミナルに紐付いているので、標準エラー出力はターミナルに紐付いてしまうからである。
コマンドの標準出力を別のコマンドの標準入力へ紐付ける仕組みはパイプと呼ばれる。
$ COMMAND1 | COMMAND2
標準エラー出力もパイプで送るのであれば、リダイクレトを使う。
$ COMMAND1 2>&1 | COMMAND2
zshやbashのマニュアルを読むともっと複雑な書き方があるが、これぐらいをしっかり身に付けておけば、普段使いには十分な気がする。
例えば、zshには、上の書き方の省略形があるが、すぐに忘れそうだ。
$ COMMAND1 |& COMMAND2