crontab Scheduled Tasks

crontab cheatsheet — edit, list, remove cron jobs. crontab -e, crontab -l, crontab -r. Schedule scripts with every time pattern. Covers environment variables and logging.

7 min read

What it is

crontab is a Unix utility that allows users to schedule commands or scripts to run periodically at fixed times, dates, or intervals. It’s the go-to for automating repetitive tasks on a server.

Installation

Linux: crontab is typically installed by default on most Linux distributions. If not, you can install it using your package manager:

sudo apt update && sudo apt install cron # Debian/Ubuntu
sudo yum update && sudo yum install cronie # CentOS/RHEL
sudo dnf update && sudo dnf install cronie # Fedora

Mac: crontab is pre-installed on macOS.

Windows: Windows uses Task Scheduler. While not crontab, it serves the same purpose. You can access it by searching for "Task Scheduler" in the Start menu. For command-line interaction, you might explore third-party tools or PowerShell equivalents.

Core Concepts

  • Cron Daemon: A background process (cron or crond) that wakes up every minute to check for scheduled jobs.
  • Crontab File: A configuration file that contains the schedule of jobs for a specific user. Each user can have their own crontab file.
  • Cron Syntax: The specific format used to define the schedule for a job.

Commands / Usage

Managing Your Crontab File

  • Edit your crontab file:

    crontab -e
    

    Opens your personal crontab file in your default editor. If the file doesn’t exist, it will be created.

  • List your crontab file:

    crontab -l
    

    Displays the contents of your personal crontab file.

  • Remove your crontab file:

    crontab -r
    

    Deletes your personal crontab file. Use with caution!

  • Edit another user’s crontab file (as root):

    sudo crontab -u username -e
    

    Edits the crontab file for the specified username.

  • List another user’s crontab file (as root):

    sudo crontab -u username -l
    

    Displays the contents of the specified username’s crontab file.

Cron Syntax

Each line in a crontab file represents a single scheduled job and follows this format:

* * * * * command_to_execute
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Special Characters:

  • * (Asterisk): Matches any value. For example, * in the hour field means "every hour."
  • , (Comma): Separates multiple values. For example, 0,15,30,45 in the minute field means "at minutes 0, 15, 30, and 45."
  • - (Hyphen): Specifies a range of values. For example, 9-17 in the hour field means "from 9 AM to 5 PM inclusive."
  • / (Slash): Specifies step values. For example, */15 in the minute field means "every 15 minutes."

Predefined Scheduling Shortcuts:

These are convenient aliases for common schedules:

  • @reboot: Run once after reboot.
  • @yearly or @annually: Run once a year, equivalent to 0 0 1 1 *.
  • @monthly: Run once a month, equivalent to 0 0 1 * *.
  • @weekly: Run once a week, equivalent to 0 0 * * 0.
  • @daily or @midnight: Run once a day, equivalent to 0 0 * * *.
  • @hourly: Run once an hour, equivalent to 0 * * * *.

Examples of Cron Syntax

  • Run a script every minute:

    * * * * * /path/to/your/script.sh
    
  • Run a script at 2:30 AM every day:

    30 2 * * * /path/to/your/script.sh
    
  • Run a script at 9 AM and 5 PM on weekdays (Monday-Friday):

    0 9,17 * * 1-5 /path/to/your/script.sh
    
  • Run a script every 15 minutes:

    */15 * * * * /path/to/your/script.sh
    
  • Run a script on the 1st of every month at midnight:

    0 0 1 * * /path/to/your/script.sh
    
  • Run a script at reboot using the shortcut:

    @reboot /path/to/your/script.sh
    

Specifying Commands and Output Redirection

  • Running a command:

    0 1 * * * /usr/bin/curl http://example.com/healthcheck
    

    Runs curl to check a URL at 1 AM daily.

  • Redirecting standard output to a file:

    0 2 * * * /path/to/your/script.sh > /var/log/script.log
    

    Appends the standard output of script.sh to script.log.

  • Redirecting standard error to a file:

    0 3 * * * /path/to/your/script.sh 2> /var/log/script.err
    

    Appends the standard error of script.sh to script.err.

  • Redirecting both standard output and standard error to a file:

    0 4 * * * /path/to/your/script.sh > /var/log/script.log 2>&1
    

    Appends both standard output and standard error to script.log.

  • Discarding all output:

    0 5 * * * /path/to/your/script.sh > /dev/null 2>&1
    

    Runs the script and discards all output.

  • Sending output via email (default behavior if not redirected): By default, cron will email any output generated by a job to the user who owns the crontab. To explicitly send output to your email address:

    0 6 * * * MAILTO="your_email@example.com" /path/to/your/script.sh
    

    Note: This requires the sendmail or equivalent MTA to be configured on your system.

Common Patterns

  • Running a Python script:

    0 7 * * * /usr/bin/python3 /home/user/scripts/my_script.py
    

    Make sure to use the full path to the Python interpreter and your script.

  • Running a Node.js script:

    0 8 * * * /usr/local/bin/node /home/user/app/server.js
    

    Use the correct path to your node executable.

  • Cleaning up old log files weekly:

    0 0 * * 0 find /var/log/myapp/ -type f -mtime +7 -delete
    

    Deletes files in /var/log/myapp/ older than 7 days, every Sunday at midnight.

  • Running a backup script nightly:

    30 1 * * * /usr/local/bin/backup.sh --full > /var/log/backup.log 2>&1
    

    Executes a backup script at 1:30 AM and logs output.

  • Checking disk space every hour and alerting if low:

    0 * * * * df -h | awk '$5 ~ /^9[0-9]%$/ { print "Disk space low: " $0 }' | mail -s "Disk Space Alert" admin@example.com
    

    Checks disk usage every hour and sends an email if any partition is 90% full or more.

  • Running a job that takes a long time only if it’s not already running:

    0 0 * * * if ! pgrep -f "my_long_running_job.sh" > /dev/null; then /path/to/my_long_running_job.sh; fi
    

    This prevents duplicate instances of a script from running simultaneously.

Gotchas

  • Environment Variables: cron runs with a minimal set of environment variables. Paths to commands might not be found. Always use absolute paths for commands and scripts (e.g., /usr/bin/php instead of php). You can also define variables at the top of your crontab file:

    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    MY_VAR="some_value"
    
    * * * * * echo $MY_VAR
    
  • Permissions: The script executed by cron runs with the permissions of the user whose crontab it is. Ensure the user has execute permissions for the script and read/write permissions for any files or directories it accesses.

  • Working Directory: cron jobs do not necessarily run from your home directory. The default working directory is usually the user’s home directory. If your script relies on being in a specific directory, cd to it explicitly within the script or in the crontab entry:

    0 10 * * * cd /var/www/html && ./deploy.sh
    
  • Editor for crontab -e: The editor used by crontab -e is determined by the EDITOR environment variable. If not set, it typically defaults to vi. You can set EDITOR in your .bashrc or .profile (e.g., export EDITOR=nano) or temporarily before running crontab -e.

  • Output Handling: By default, cron emails any output (stdout or stderr) to the user. If you don’t want emails, explicitly redirect output to /dev/null. If you want to log output, redirect it to a file.

  • System Time vs. User Time: cron uses the system’s time. Ensure your system clock is accurate.

  • Special Characters: Backslashes (\) need to be escaped (\\) in crontab entries if they are part of a literal string. The percent sign (%) is also special: it signifies the end of the command and the start of standard input. If you need a literal percent sign, escape it with a backslash (\%).

  • @reboot Execution Order: Jobs scheduled with @reboot might run before all system services are fully initialized. If your @reboot job depends on other services (like network connectivity or databases), you might need to add delays or checks within your script.

  • User Crontabs vs. System Crontabs: While crontab -e is for user-specific jobs, system-wide cron jobs are typically managed in /etc/crontab and directories like /etc/cron.d/, /etc/cron.hourly/, /etc/cron.daily/, etc. /etc/crontab has an additional field for the user to run the command as.