cron cheatsheet

System wide crontab

/etc/crontab

cron.d

Other crontabs can be put into /etc/cron.d/

Create a user specific crontab

As user:

  • crontab -e

The user specific crontabs are saved in /var/spool/cron/crontabs/

Deactivate cron

  • service cron stop

Send output to specific email address

Per default cron sends output to the owner of the crontab file.

To redirect use the MAILTO variable. Put on top of the crontab:

MAILTO="my@example.com"

Use bash (allows "&&", ...)

SHELL=/bin/bash

Set a custom home directory e.g. prevent append "cd foo" before commands

HOME=/home/myuser/mydir

Every 5 minutes

*/5 * * * *   root   /path/to/command

Use @reboot

# use sleep, because network and other services are'nt up yet
@reboot         sleep 60 && mycommand

# test
@reboot         sleep 60 && ls -la 2>&1 >> /home/myuser/reboot.log

Quiet cron (Output redirection)

script.sh > /dev/null 2>&1

Quiet cron, but send errors

script.sh > /dev/null

Log output into logfile (stdout & stderr), but swallow stdout output

-> All output is appended to logfile, but in case of errors a cron email ist sent

04 03  * * *   root    /etc/script.sh > >(tee --append /var/log/script.log > /dev/null) 2> >(tee --append /var/log/script.log >&2)

Or better use this script. Put it into "/usr/local/bin/cronlog.sh" and make it executable.

#!/bin/bash
# 2025-09-15 klemens.ullmann-marx@ull.at

set -o errexit    # same as -e : exit on error
set -o nounset    # same as -u : error on unset variables
set -o pipefail   # make pipelines fail if any command fails => returns error code of first cmd

# Explain usage if we got less than two arguments
# By convention the explanation is outputed to stderr (>&2)
if [[ $# -lt 2 ]]; then
  echo "cronlog.sh - Run a command, log stdout and stderr to a file, but only show stderr."
  echo "Very useful for cron jobs where we want to log complete output, but only passthrough stderr to trigger a cron email with MAILTO=me@example.com"
  echo "Usage: cronlog.sh <logfile> <command> [args...]" >&2
  echo "Example: 'cronlog.sh /tmp/my.log ls /home /nonexistent'" >&2
  exit 1
fi

logfile="$1"
shift   # drop logfile from arguments, leaving only the command for "$@?

# Write log header
{
  echo "===== [$(date '+%Y-%m-%d %H:%M:%S')] Running: $* ====="
} >> "$logfile"

# Run the given command
# - stdout -> logfile only
# - stderr -> logfile + terminal
"$@" \
  > >(tee --append "$logfile" > /dev/null) \
  2> >(tee --append "$logfile" >&2)

Run jobs with very low priority

nice -n 19 ionice -c3 script.sh

Dont start a cronjob again before it's finished

http://blog.dustinkirkland.com/2011/02/introducing-run-one-and-run-this-one.html

sudo apt-get install run-one

run-one script.sh

Script aborted or crashed?

rm ~/.cache/run-one/*

Check which scripts are execute by e.g. cron.daily

run-parts --test /etc/cron.daily