すべての出力をフォルダに書き込むcronラッパーを作成したいと思います$CRON_LOG_DIR
。
使用法は次のとおりです。
* * * * * $CRON_WRAPPER "<job name>" "command"
stdout
これにより、次stderr
の出力全体が記録されますcommand
。
$CRON_LOG_DIR/<date>/<job_name>/command_timestamp.log
以下のスクリプトを使用していますが、$CRON_WRAPPER
コマンドが複数のコマンドで構成されているケースは記録されていないようですstdout
。command
* * * * * $CRON_WRAPPER "<job name>" "command1 && command2 && command3"
なぜ?
以下は完全な内容ですCRON_WRAPPER
#!/usr/bin/env zsh
COMMAND_NAME=$1
shift
DATE=$(date +%B_%d_%Y)
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
THIS_CRON_LOG_DIR=$CRON_LOG_DIR/$DATE
mkdir -p $THIS_CRON_LOG_DIR
CRON_LOG_FILE=${THIS_CRON_LOG_DIR}/${COMMAND_NAME}_${TIMESTAMP}.log
# Joining commands:
to_join=$@
joined=$(printf ",%s" "${to_join[@]}")
# Redirecting all output to our logging file:
joined=${joined:1}">> $CRON_LOG_FILE 2>&1"
# Finally evaluating the command
eval $joined
答え1
スクリプトの最初の引数があり、jobname
2番目の引数があるcommand1 && command2 && command3
場合、変数にビルドするコマンドは次joined
のようになります。
command1 && command2 && command3>> /path/to/cron/log/dir/May_12_2015/jobname_2015-05-12_01-09-25.log 2>&1
この文字列を呼び出すとeval
正常に解析されます。リダイレクトは「command3」でのみ機能します。
2番目の引数をシェルフラグメントの接頭辞ではなくシェルフラグメントとして扱おうとします。だからそれに接続しないでください。リダイレクトは、eval
解析する必要がある文字列を介さずにスクリプトから直接指定するため、以下ではなくスクリプトに直接属します。シェルに特殊文字を含めるとjobname
コードがハングします。たとえば、$CRON_WRAPPER $(touch /tmp/foo) stuff
コードが実行されますtouch /tmp/foo
。
スクリプトのもう1つの問題は、パラメータが2つ以上の場合、パラメータ間にカンマが追加されることです。これは意味がありません。スペースで連結する方が合理的です"$*
。簡単です。 (今行っている操作は、カンマを区切り文字として使用して接続するのは複雑すぎます。zshでは${(j:,:)@}
。)
# Joining commands:
次に始まるスクリプトの部分を置き換えます。
eval "$*" >>$CRON_LOG_FILE 2>&1