GNU/Linux >> Linux の 問題 >  >> Linux

毎週の cron ジョブをテストする

ロック ファイルを使用し、cron ジョブを毎分実行するように設定します。 (crontab -e および * * * * * /path/to/job を使用) そうすれば、ファイルを編集し続けることができ、毎分テストされます。さらに、ロック ファイルに触れるだけで cronjob を停止できます。

    #!/bin/sh
    if [ -e /tmp/cronlock ]
    then
        echo "cronjob locked"
        exit 1
    fi

    touch /tmp/cronlock
    <...do your regular cron here ....>
    rm -f /tmp/cronlock

すぐには互換性がなかった cron のいくつかをいじった後、次のアプローチがデバッグに適していることがわかりました:

crontab -e

* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log

これにより、タスクが 1 分に 1 回実行され、 /tmp/cron_debug_log.log を確認するだけで済みます。

これはまさにあなたが探している「ファイア ジョブ」ではありませんが、最初は cron で機能しなかったスクリプトをデバッグするときに、これが大いに役立ちました。


あなたの質問の範囲を少し超えています...しかし、これが私がすることです.

「cron ジョブをテストするにはどうすればよいですか?」質問は、「他のプログラムによって起動された非対話的なコンテキストで実行されるスクリプトをテストするにはどうすればよいですか?」と密接に関連しています。 cron では、トリガーは時間条件ですが、他の多くの *nix 機能ではスクリプトまたはスクリプト フラグメントを非対話的な方法で起動します。これらのスクリプトが実行される条件には予期しないものが含まれていることが多く、バグが整理されるまでは破損の原因となります。 (参照:https://stackoverflow.com/a/17805088/237059 )

この問題に対する一般的なアプローチがあると役に立ちます。

私のお気に入りの手法の 1 つは、'crontest' という名前のスクリプトを作成することです。 cron 内から GNU screen セッション内でターゲット コマンドを起動するため、別のターミナルを接続して何が起こっているかを確認したり、スクリプトとやり取りしたり、デバッガーを使用したりすることもできます。

これを設定するには、crontab エントリで「すべての星」を使用し、コマンド ラインの最初のコマンドとして crontest を指定します。例:

* * * * * crontest /command/to/be/tested --param1 --param2

したがって、cron は毎分コマンドを実行しますが、crontest は一度に 1 つのインスタンスのみが実行されるようにします。コマンドの実行に時間がかかる場合は、「screen -x」を実行してアタッチし、実行を監視できます。コマンドがスクリプトの場合、「読み取り」コマンドを先頭に配置して停止し、画面の添付が完了するのを待つことができます (添付後に Enter キーを押します)

コマンドが bash スクリプトの場合、代わりにこれを実行できます:

* * * * * crontest --bashdb /command/to/be/tested --param1 --param2

ここで、「screen -x」でアタッチすると、インタラクティブな bashdb セッションに直面し、コードをステップ実行したり、変数を調べたりすることができます。

#!/bin/bash

# crontest
# See https://github.com/Stabledog/crontest for canonical source.

# Test wrapper for cron tasks.  The suggested use is:
#
#  1. When adding your cron job, use all 5 stars to make it run every minute
#  2. Wrap the command in crontest
#        
#
#  Example:
#
#  $ crontab -e
#     * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
#  Now, cron will run your job every minute, but crontest will only allow one
#  instance to run at a time.  
#
#  crontest always wraps the command in "screen -d -m" if possible, so you can
#  use "screen -x" to attach and interact with the job.   
#
#  If --bashdb is used, the command line will be passed to bashdb.  Thus you
#  can attach with "screen -x" and debug the remaining command in context.
#
#  NOTES:
#   - crontest can be used in other contexts, it doesn't have to be a cron job.
#       Any place where commands are invoked without an interactive terminal and
#       may need to be debugged.
#
#   - crontest writes its own stuff to /tmp/crontest.log
#
#   - If GNU screen isn't available, neither is --bashdb
#

crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="[email protected]"
screenBin=$(which screen 2>/dev/null)

function errExit {
    echo "[-err-] [email protected]" | tee -a $crontestLog >&2
}

function log {
    echo "[-stat-] [email protected]" >> $crontestLog
}

function parseArgs {
    while [[ ! -z $1 ]]; do
        case $1 in
            --bashdb)
                if ! $useScreen; then
                    errExit "--bashdb invalid in crontest because GNU screen not installed"
                fi
                if ! which bashdb &>/dev/null; then
                    errExit "--bashdb invalid in crontest: no bashdb on the PATH"
                fi

                useBashdb=true
                ;;
            --)
                shift
                innerArgs="[email protected]"
                return 0
                ;;
            *)
                innerArgs="[email protected]"
                return 0
                ;;
        esac
        shift
    done
}

if [[ -z  $sourceMe ]]; then
    # Lock the lockfile (no, we do not wish to follow the standard
    # advice of wrapping this in a subshell!)
    exec 9>$lockfile
    flock -n 9 || exit 1

    # Zap any old log data:
    [[ -f $crontestLog ]] && rm -f $crontestLog

    parseArgs "[email protected]"

    log "crontest starting at $(date)"
    log "Raw command line: [email protected]"
    log "Inner args: [email protected]"
    log "screenBin: $screenBin"
    log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
    log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"

    # Were building a command line.
    cmdline=""

    # If screen is available, put the task inside a pseudo-terminal
    # owned by screen.  That allows the developer to do a "screen -x" to
    # interact with the running command:
    if $useScreen; then
        cmdline="$screenBin -D -m "
    fi

    # If bashdb is installed and --bashdb is specified on the command line,
    # pass the command to bashdb.  This allows the developer to do a "screen -x" to
    # interactively debug a bash shell script:
    if $useBashdb; then
        cmdline="$cmdline $(which bashdb) "
    fi

    # Finally, append the target command and params:
    cmdline="$cmdline $innerArgs"

    log "cmdline: $cmdline"


    # And run the whole schlock:
    $cmdline 

    res=$?

    log "Command result: $res"


    echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog

    # Release the lock:
    9<&-
fi

cron と同じように、次を root として実行します。 :

run-parts -v /etc/cron.weekly

... または、「ディレクトリではありません:-v」エラーが発生した場合は次のエラー:

run-parts /etc/cron.weekly -v

オプション -v 実行前にスクリプト名を出力します。


Linux
  1. cronジョブの使用とポリシー

  2. Linux:フォアグラウンドで cron ジョブを実行する

  3. cron ジョブを使用してログ ファイルを削除する

  1. TrueNASでcronジョブを設定する方法

  2. cronジョブを設定する方法

  3. cron ジョブが時々実行されない

  1. cronジョブが実行されていませんか?

  2. これらのcronジョブの間違いを犯していますか?

  3. 1 時間ごとに実行可能ファイルを実行するように cron ジョブを設定する方法は?