Test a weekly cron job [closed] Test a weekly cron job [closed] linux linux

Test a weekly cron job [closed]


Just do what cron does, run the following as root:

run-parts -v /etc/cron.weekly

... or the next one if you receive the "Not a directory: -v" error:

run-parts /etc/cron.weekly -v

Option -v prints the script names before they are run.


A wee bit beyond the scope of your question... but here's what I do.

The "how do I test a cron job?" question is closely connected to "how do I test scripts that run in non-interactive contexts launched by other programs?" In cron, the trigger is some time condition, but lots of other *nix facilities launch scripts or script fragments in non-interactive ways, and often the conditions in which those scripts run contain something unexpected and cause breakage until the bugs are sorted out. (See also: https://stackoverflow.com/a/17805088/237059 )

A general approach to this problem is helpful to have.

One of my favorite techniques is to use a script I wrote called 'crontest'. It launches the target command inside a GNU screen session from within cron, so that you can attach with a separate terminal to see what's going on, interact with the script, even use a debugger.

To set this up, you would use "all stars" in your crontab entry, and specify crontest as the first command on the command line, e.g.:

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

So now cron will run your command every minute, but crontest will ensure that only one instance runs at a time. If the command takes time to run, you can do a "screen -x" to attach and watch it run. If the command is a script, you can put a "read" command at the top to make it stop and wait for the screen attachment to complete (hit enter after attaching)

If your command is a bash script, you can do this instead:

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

Now, if you attach with "screen -x", you'll be facing an interactive bashdb session, and you can step through the code, examine variables, etc.

#!/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.loglockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )useBashdb=falseuseScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )innerArgs="$@"screenBin=$(which screen 2>/dev/null)function errExit {    echo "[-err-] $@" | tee -a $crontestLog >&2}function log {    echo "[-stat-] $@" >> $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="$@"                return 0                ;;            *)                innerArgs="$@"                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 "$@"    log "crontest starting at $(date)"    log "Raw command line: $@"    log "Inner args: $@"    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


After messing about with some stuff in cron which wasn't instantly compatible I found that the following approach was nice for debugging:

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

This will run the task once a minute and you can simply look in the /tmp/cron_debug_log.log file to figure out what is going on.

It is not exactly the "fire job" you might be looking for, but this helped me a lot when debugging a script that didn't work in cron at first.