Skip to content

How to test a cron job

Jeremy Davis edited this page Mar 3, 2017 · 4 revisions

Get your server's cron environment

Create a new cron job to run every minute (smallest increment cron supports). This is so you don't have to wait too long. The new cron job needs to output the cron job environment of the desired user; e.g. for root:

root@core ~# USER=root
root@core ~# echo "*   * * * *    $USER            env > /tmp/env.$USER" > /etc/cron.d/getenv

Then wait a minute and read what cron outputs:

root@core ~# cat /tmp/env.$USER
LANGUAGE=en_US.UTF-8
HOME=/root
LC_CTYPE=C
LOGNAME=root
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
LC_ALL=C
PWD=/root

We can confirm that this is indeed as it should be:

root@core ~# env --ignore-environment - $(cat /tmp/env.$USER) env > /tmp/env.duplicated
root@core ~# md5sum /tmp/env.{$USER,duplicated}
435e12492a8aeaaedfd42c5791156eb2  /tmp/env.root
435e12492a8aeaaedfd42c5791156eb2  /tmp/env.duplicated

Checking and testing your cron job

If the cron job is in /etc/cron.{daily,weekly,monthly}/ it needs to be executable to run. Looking for the executable "x" in the output of ls -l is arguably the easiest way to check:

root@core ~# ls -l /etc/cron.weekly/
total 12
-rw-r--r-- 1 root root 650 Mar  3 02:26 new-cron-job-disabled
-rwxr-xr-x 1 root root 226 Apr  8  2016 old-cron-job-executable

new-cron-job-disabled is not executable, whereas old-cron-job-executable is. If your cron job is not executable, then it won't run. If you don't want it to run by default; i.e. unless explicitly enabled by the user, then it's legitimate to ship with a disabled (non-executable) cron job. To make a cron job executable use chmod +x:

root@core ~# chmod +x /etc/cron.weekly/new-cron-job-disabled

Actually I'm going to rename it something more appropriate and demonstrate that it's now executable:

root@core ~# mv /etc/cron.weekly/new-cron-job-disabled /etc/cron.weekly/new-cron-job-enabled
root@core ~# ls -l /etc/cron.weekly/new-cron-job-enabled
-rwxr-xr-x 1 root root 650 Mar  3 02:26 /etc/cron.weekly/new-cron-job-enabled

Note: cron jobs in /etc/cron.d/ DO NOT need to be executable. They will always run regardless of their executable status!

Now armed with our environment, we can test run the cron job:

env --ignore-environment - $(cat /tmp/env.$USER) /bin/sh /etc/cron.weekly/new-cron-job-enabled

Some gotchas to watch out for

Gotcha 1: This will execute the cron job, even if it's not executable! So you need to also test that it's executable (see above).

Gotcha 2: Watch out you don't run /bin/bash instead of /bin/sh. By default cron jobs always run under /bin/sh. Bash may change the execution environment by running various bashrc / profile commands. If your script won't run under sh and you need bash, then it needs to be explicitly set within your cron job. I.e.: in your cron job file, near the top add SHELL=/bin/bash. If you wish to load particular environment variables, add them there too. Alternatively load a separate file with your desired environment. E.g.: BASH_ENV="/path/to/env".

Clean up

When you're done, clean up:

root@core ~# rm /etc/cron.d/getenv
root@core ~# rm /tmp/env.*