
次の行を含む cron 経由で実行されるスクリプトがあります。
0 * * * * (/var/script.sh | tee -a /var/script.log)
stdout
通常の出力とエラーの出力の両方をキャプチャするように cron エントリを書き換えるにはどうすればよいでしょうstderr
か。これらは別のファイルに配置する必要があります。
答え1
cron
ジョブはデフォルトで実行されsh
、sh
Bourne または 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)csh
、zsh
または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
、なくても実行できます。tee
MULT_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
、、、、) には、パイプラインの任意のコンポーネントのエラーを報告できるオプションがあります。ksh93
zsh
yash
mksh
pipefail
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
また、括弧を削除したことにも注意してください。サブシェルでスクリプトを実行しても意味がありません。