通常出力(stdout)とエラー出力(stderr)をキャプチャする

通常出力(stdout)とエラー出力(stderr)をキャプチャする

次の行を含む cron 経由で実行されるスクリプトがあります。

0 * * * * (/var/script.sh | tee -a /var/script.log)

stdout通常の出力とエラーの出力の両方をキャプチャするように cron エントリを書き換えるにはどうすればよいでしょうstderrか。これらは別のファイルに配置する必要があります。

答え1

cronジョブはデフォルトで実行されshshBourne または POSIXshまたは互換であるかどうかに関係なく、構文は次のようになります。

0 * * * * /var/script.sh 2>&1 | tee -a /var/script.log

ここで、|左側のコマンドの stdout (fd 1) がパイプの書き込み側に接続され、右側のコマンドの stdin (fd 0) が読み取り側に接続されたパイプで、両側の 2 つのコマンドが並行して実行されます。

2>&1左側に追加することで、 fd 2 (stderr) は fd 1 が指すのと同じリソース、つまりパイプの書き込み側を指すようになり、 の通常出力とエラー出力の両方script.shがパイプに送られますtee

teeはそれを stdout (cron ジョブの場合は、ユーザーに電子メールを送信するために使用されるパイプまたは一時ファイルのいずれか) と の両方に書き込みますscript.log

この構文はシェルでも機能しますfish

(t)cshzshまたはbash(4.0 以降) を使用すると、次の操作も実行できます。

SHELL=/bin/zsh # or tcsh, bash ...
0 * * * * /var/script.sh |& tee -a /var/script.log

(ここでは、別のシェルを使用してコマンド ラインを解釈するようにSHELL=/bin/zsh指示します)。cron

では、の代わりにfishを使用します。&||&

rc( の後継となる) または導関数を使用する場合sh、構文は次のようになります。

SHELL=/bin/rc # or es, akanga
0 * * * * /var/script.sh >[2=1] | tee -a /var/script.log

を使用すると、 その機能のおかげでzsh、なくても実行できます。teeMULT_IOS

SHELL=/bin/zsh
0 * * * * /var/script.sh >&1 2>&2 >>& /var/script.log

script.shこれには、 の終了ステータスが保持されるという利点もあり、script.shの stderr も元の stderr に送られ続けますscript.log(ただし、stdout と stderr が一般的に同じ場所に送られる cron ジョブでは、それほど大きな違いはありません)。

いくつかの Bourne/POSIX のようなシェル (少なくともbash、、、、) には、パイプラインの任意のコンポーネントのエラーを報告できるオプションがあります。ksh93zshyashmkshpipefail

SHELL=/bin/ksh # or zsh, bash...
0 * * * * set -o pipefail && /var/script.sh 2>&1 | tee -a /var/script.log

答え2

cronは出力を生成するcronジョブについて通知します。その結果をメールで送ります。cronからメールを受け取りたくない場合は、ジョブが出力を生成しないようにします。 を使用せずtee、出力をリダイレクトするだけです。

0 * * * * /var/script.sh >> /var/script.log 2>&1

また、括弧を削除したことにも注意してください。サブシェルでスクリプトを実行しても意味がありません。

関連情報