デフォルトの挙動
GNU coreutils版のteeコマンドは、--output-errorを指定しない場合、パイプへの書き込みエラーでは即座に終了し、それ以外の出力先へのエラーは警告だけして処理を続ける。
$ mkdir baddir
$ echo hello | tee file1.txt baddir file2.txt
hello
tee: baddir: Is a directory
$ cat file1.txt file2.txt
hello
hello
baddirへの書き込みはエラーになるが、file1.txtとfile2.txtにはhelloが書き込まれている。
–output-errorでMODEを指定する
--output-error=MODEでこの挙動を変更できる。
コマンド | tee --output-error=MODE ファイルパス
| MODE | 挙動 |
|---|---|
| warn | すべての出力先へのエラーを警告し、処理を続ける |
| warn-nopipe | パイプ以外の出力先へのエラーを警告し、処理を続ける(-pのデフォルト) |
| exit | いずれかの出力先へのエラーで即座に終了する |
| exit-nopipe | パイプ以外の出力先へのエラーで即座に終了する |
exitで即座に終了する例
exitを指定すると、エラーが発生した時点で標準入力の読み込みも含めて即座に終了する。
$ echo hello | tee --output-error=exit file3.txt baddir file4.txt
tee: baddir: Is a directory
$ cat file3.txt
$ ls file4.txt
ls: cannot access 'file4.txt': No such file or directory
baddirより前に指定したfile3.txtもオープン自体には成功している。しかしbaddirのオープンエラーで即座に終了するため、標準入力を読み込む前に処理が止まり、中身は空のままになる。デフォルトの挙動とは異なり、正常にオープンできたファイルへの書き込みも行われない。
warnでパイプのエラーも警告に変える
warnを指定すると、パイプへの書き込みエラーでも終了せず処理を続ける。GNU teeの-pオプションと似た効果になる。
$ seq 1 5000000 | tee --output-error=warn out.txt | head -n 1
tee: 'standard output': Broken pipe
1
$ wc -l out.txt
5000000 out.txt
head -n 1によってパイプが閉じられても、out.txtにはすべての行が書き込まれている。
用途
複数の出力先へ同時に書き込む際、1つでも失敗したら即座に止めたいのか、書き込めるところまでは続けたいのかで--output-errorのMODEを選ぶ。ログ収集など一部の出力先が失敗しても他を続けたい場合はwarn、設定ファイルの一括更新など中途半端な状態を避けたい場合はexitが向く。
参考: 【tee】GNU teeの-pでパイプ向けモードにする
\第一線のプログラマーの行動原理を学べる!/
