すべての出力を記録する通常のクローンラッパー

すべての出力を記録する通常のクローンラッパー

すべての出力をフォルダに書き込むcronラッパーを作成したいと思います$CRON_LOG_DIR

使用法は次のとおりです。

* * * * * $CRON_WRAPPER "<job name>" "command"

stdoutこれにより、次stderrの出力全体が記録されますcommand

$CRON_LOG_DIR/<date>/<job_name>/command_timestamp.log

以下のスクリプトを使用していますが、$CRON_WRAPPERコマンドが複数のコマンドで構成されているケースは記録されていないようですstdoutcommand

* * * * * $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

スクリプトの最初の引数があり、jobname2番目の引数がある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

関連情報