1. ホーム
  2. linux

[解決済み] パイプで "tee "を使用しているときに、標準エラーをファイルに書き込むにはどうすればよいですか?

2022-03-15 18:23:38

質問

の使い方は知っています。 tee を書き込むと、出力されます ( 標準出力 ) の aaa.sh から bbb.out を、ターミナルに表示したままです。

./aaa.sh | tee bbb.out

また、今度はどのように書けばいいのでしょうか? 標準エラー という名前のファイルに ccc.out を、表示させたまま?

どのように解決するのですか?

ターミナルでSTDERRとSTDOUTをまだ見たいのだと思います。 Josh Kelleyの回答でもいいのですが、私は、STDERRとSTDOUTを表示するために tail ログファイルを出力するバックグラウンドで、非常にハック的で不格好です。 exra FD を保持し、終了後に kill してクリーンアップする必要がありますが、これは技術的には trap '...' EXIT .

もっといい方法があるのですが、あなたはもうそれを発見しましたね。 tee .

ただ、標準出力にだけ使うのではなく、標準出力用のTeeと標準エラー用のTeeを用意しましょう。 どのようにこれを実現するのでしょうか? プロセス代替とファイルリダイレクトです。

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

分割して説明しましょう。

> >(..)

>(...) (プロセス代行) は FIFO を作成し、その FIFO を使って tee をリッスンする。 そして > (ファイルリダイレクト) を使って、STDOUT を command をFIFOにコピーして、最初の tee がリッスンしています。

2番目も同じです。

2> >(tee -a stderr.log >&2)

再びプロセス置換を使用して tee プロセスで、STDIN から読み込み、それを stderr.log . tee はその入力をSTDOUTに出力しますが、その入力は私たちのSTDERRであるため、私たちは tee のSTDOUTを再び我々のSTDERRに戻す。 次に、ファイルリダイレクトを使って command のSTDERRをFIFOの入力( tee のSTDIN)。

参照 http://mywiki.wooledge.org/BashGuide/InputAndOutput

プロセス代替は、あなたが選択したボーナスとして得られる本当に素敵なものの1つです。 bash とは対照的に、シェルとして sh (POSIXまたはBourne)を使用します。


sh の場合、手動で行う必要があります。

out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"