次のコマンドはREADYを標準出力へ、WARNを標準エラーへ出す。
標準エラーのリダイレクトはパイプより先に適用されている。
bash -c 'printf "READY\n"; printf "WARN\n" >&2' \
2>errors.log | tee output.log端末表示と2つのファイル内容として正しい組み合わせはどれか。
パイプが渡すのは標準出力だけです。標準エラーは2>errors.logへ送られ、teeは受け取ったREADYを画面とoutput.logの両方へ書きます。
詳細解説
READYはteeが端末とoutput.logへ書き、WARNは2>でerrors.logへ送られます。
正しい選択肢です。READYは標準出力なのでパイプを通ってteeへ届きます。teeはREADYをoutput.logへ保存し、同時に端末へ再出力します。
WARNは標準エラーへ出され、パイプへ入る前に2>errors.logで別ファイルへ送られます。
WARNはパイプに入らず、標準エラーのリダイレクト先へ送られます。
誤りです。WARNをREADYと同じパイプへ流すには、標準エラーを標準出力へ統合する2>&1などが必要です。このコマンドでは2>errors.logが指定されています。
そのためerrors.logは空ではなくWARNを含み、output.logにはREADYだけが入ります。
端末にはteeが標準出力へ再出力するREADYが表示されます。
誤りです。WARNはerrors.logへ送られるため端末には表示されません。一方、teeは受け取ったREADYを自分の標準出力へ書くため、端末にはREADYが表示されます。
teeはファイル保存だけを行うコマンドではない点が重要です。
teeはファイルだけでなく標準出力にも書きます。WARNはパイプへ統合されていません。
誤りです。teeは標準入力をoutput.logへ保存すると同時に、標準出力へも書きます。したがって端末表示は空になりません。
またWARNは標準出力へ統合されていないため、output.logではなくerrors.logへ入ります。
実際に確かめる
一時的な検証環境で実行できる例です。
bash -c 'printf "READY\n"; printf "WARN\n" >&2' \
2>errors.log | tee output.log
printf '%s\n' '--- output.log ---'
cat output.log
printf '%s\n' '--- errors.log ---'
cat errors.log期待される結果
READY
--- output.log ---
READY
--- errors.log ---
WARN理解のポイント
- ファイルディスクリプタ1と2
- パイプが標準出力だけを渡すこと
- teeが画面とファイルの両方へ出力すること
確認時の注意
- 確認環境:
- 端末、output.log、errors.logの3か所をそれぞれ確認します。
- 既存ファイルを残したい場合は>ではなく>>による追記を検討します。
基礎のおさらい
ファイルディスクリプタ
標準入力は0、標準出力は1、標準エラーは2です。リダイレクトでは、どの番号をどこへ接続するかを指定します。
パイプが渡すもの
通常の|は左コマンドの標準出力を右コマンドの標準入力へ接続します。標準エラーは自動では含まれません。
teeの二重出力
teeは標準入力をファイルへ書きながら、同じ内容を標準出力へも流します。ログ保存と画面確認を両立できます。
順序で意味が変わる
2>&1 >fileと>file 2>&1では接続結果が異なります。リダイレクトは左から処理されるため、各時点で1と2がどこを指すか追います。