GNU/Linux >> Linux の 問題 >  >> Linux

パイプでティーを使用しているときにstderrをファイルに書き込むにはどうすればよいですか?

端末で STDERR と STDOUT を引き続き表示したいと思っていると思います。あなたは Josh Kelley の答えに行くことができますが、私は tail を保持していることに気づきました ログファイルを出力するバックグラウンドで非常にハックでぎこちない。 exra FD を保持し、後でそれを強制終了してクリーンアップを行う必要があることに注意してください。技術的には trap '...' EXIT でそれを行う必要があります。 .

これを行うためのより良い方法があり、あなたはすでにそれを発見しています:tee .

stdout に使用するだけでなく、stdout 用のティーと stderr 用のティーを用意してください。これをどのように達成しますか?プロセス置換とファイル リダイレクト:

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

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

> >(..)

>(...) (プロセス置換) FIFO を作成し、tee を許可します それを聞いてください。次に、> を使用します。 (ファイルリダイレクト) command の STDOUT をリダイレクトする 最初の tee の FIFO に

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 を参照

プロセス置換は、bash を選択したボーナスとして得られる、本当に素晴らしいものの 1 つです。 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"

なぜ単純に:

./aaa.sh 2>&1 | tee -a log

これは単純に stderr をリダイレクトします stdout へ であるため、tee はログと画面の両方にエコーします。他のソリューションのいくつかは非常に複雑に見えるため、何かが欠けている可能性があります。

注: bash バージョン 4 以降、 |& を使用できます 2>&1 | の省略形として :

./aaa.sh |& tee -a log

これは、Google 経由でこれを見つけた人に役立つかもしれません。試してみたいサンプルのコメントを外してください。もちろん、出力ファイルの名前を自由に変更してください。

#!/bin/bash

STATUSFILE=x.out
LOGFILE=x.log

### All output to screen
### Do nothing, this is the default


### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1


### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1


### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)


### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)


### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}


### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)


### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}


### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)


echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}

Linux
  1. 別のファイルに書き込む方法は?

  2. Btrfsでデータをコピーせずにファイルを複製するにはどうすればよいですか?

  3. 変数を使用してBashを使用して複数行の文字列を記述する方法は?

  1. sudoとしてファイルに追加する方法は?

  2. ddを使用してFFでファイルをパディングする方法は?

  3. grep コマンドを使用して Linux で name=php.ini のファイルを検索する方法

  1. LinuxでCでファイルを書く方法は?

  2. awkを使用してファイルをインプレースで変更するには? (sed -i と同様)

  3. teeを使用してSTDERRおよびSTDOUTをファイルにキャプチャする