Skip to content
jamieonkeys.dev

Running PHP and shell scripts as cron jobs

Automate tasks on your web server with cron

Cron jobs are commands or scripts that run on a web server automatically at set intervals (every 15 minutes, once a day, twice a month etc.) My site wrestle.buzz uses a few of them (including to run an API call and clear the cache). I thought I’d document the process of setting one up.

Primer permalink

You can add cron jobs directly in a file called crontab (here’s an example doing that on Ubuntu), or via cPanel.

Scripts, whether they’re shell (.sh) or PHP, need 755 (execute) permissions to run (chmod 755 my_script.sh).

Additionally absolute paths (e.g. /home/user123/www/my.site/scripts/my_script.sh) should be used when calling scripts.

By default you’ll get an email each time a cron job runs. You can alternatively output to /dev/null to avoid getting those emails. I chose to output to a (non-null) log file. Any errors in the execution of your script will be written to this file, so it’s useful in keeping an eye out for problems. If the cron job is successful the output file should be zero bytes.

Example permalink

One of the shell scripts I run via cron is called delete_cache.sh. It deletes files in the cache (let’s call them .tmp files here) that were created over five days previous. It looks something like this:

#!/bin/bash
shopt -s extglob

find /home/user123/www/my.site/cache -type f -mtime +5 -name '*.tmp' -exec rm {} \;

shopt -u extglob

Note that within the script I use an absolute path to point to the cache directory. To test this particular script — since we’re deleting files — you might want to run it first without the command to actually delete:

find /home/user123/www/my.site/cache -type f -mtime +5 -name '*.tmp'

You can then call this script in a cron job:

0 0 * * * /home/user123/www/my.site/scripts/delete_cache.sh >/home/user123/tmp/cron.delete-cache.log 2>&1

The bit at the beginning is called a ‘cron expression’, and it determines how frequently the job runs. 0 0 * * * means ‘run once a day’. Other examples are 0 */6 * * * (‘run every six hours’) or */15 * * * * (‘run every fifteen minutes’). crontab.guru is a tool that can help with these expressions.

On success the job should write a blank file at cron.trending.delete-cache.log. Any errors will be written to this file, too.

PHP permalink

You can execute PHP scripts, too:

/usr/local/bin/php /home/user123/my.site/php/my_script.php >/home/user123/tmp/cron.my_script.dev.log 2>&1

If you’re including other files in the PHP file you’re running, you’ll need to use absolute paths so the files to be included can be found. set_include_path() is useful in this regard:

set_include_path('/home/user123/my.site/php/');
require_once('functions.php');

Also specify an absolute path if you’re writing files:

file_put_contents("/home/user123/my.site/files/my_file.html", $contents);