すべての出力をファイルにリダイレクトし、stderrも別のファイルにリダイレクトする必要があります。これは簡単なことですか?
この例では、私のコマンドが次のようになるとします。
php /tmp/doWork.php
以下を使用して、出力を別々のファイルに出力できます。
php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file
に基づいてこれ、私は次のことを試みます:
php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file
しかし、これは単にstdoutとstderrを置く/tmp/stdboth_file
だけです/tmp/stderr_file
。
答え1
zsh
以下zsh
の特徴がありますmultios
。
your-cmd 2> stdout+stderr.log >&2 2> stderr.log
fd 2は2回リダイレクトされるため、実装はzsh
それtee
を2つのファイルに内部的に送信します。
bash
(またはBourneなどのシェル(ここで動作するためにzsh
無効にする必要がある場合を除くmultios
))を使用して、tee
次のように手動で実行できます。
{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
your-cmd
zsh
( . の終了状態が失われ$pipestatus[1]
ても、その内容がbash
含まれています"${PIPESTATUS[0]}"
(リダイレクトがstderr+stdout.log
失敗しなかったと仮定)。
pidを記録するにはyour-cmd
:
{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
そしてyash
それプロセスリダイレクト特徴:
your-cmd > stdout+stderr.log 2>(tee stderr.log)
(ただし、yash
コマンドが終了するのを待たないため、tee
次のコマンドを実行するまでログファイルが完了しないことがあります。)
同様のことができます(同じ注意事項があります)。プロセスの交換一緒にしてください:bash
zsh
ksh93
{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log
バックグラウンドで実行してPIDを取得するには:
(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!
そしてrc
:
{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log
rc
パイプを使用すると、パイプに関連付けられたファイル記述子を指定できます。他のシェルでは、左側のコマンドのfd 1と右側のコマンドのfd 0は常に同じです(したがって、ファイル記述子を移動するためにfd 3を使用して上記の小さなダンスを行います)。または、失敗するrc
と失敗が報告されますが、正確な数字が失われる可能性があります。your-cmd
tee