# Cron Quick Reference

*Job scheduling, crontab syntax, special strings, logging*

> Source: crontab(5) Manual Page · MIT

## Syntax

### Crontab Format

```
# ┌───── minute (0-59)
# │ ┌───── hour (0-23)
# │ │ ┌───── day of month (1-31)
# │ │ │ ┌───── month (1-12)
# │ │ │ │ ┌───── day of week (0-7, 0&7=Sun)
# * * * * * command
```

### Field Values

| Command | Description |
|---------|-------------|
| `*` | Any value (wildcard) |
| `,` | Value list: `1,3,5` |
| `-` | Range: `1-5` |
| `/` | Step: `*/10` (every 10) |
| `0-59` | Minutes range |
| `0-23` | Hours range |
| `1-31` | Day of month range |
| `1-12` | Month range (or JAN-DEC) |
| `0-7` | Day of week (0&7=Sun, or SUN-SAT) |

## Special Strings

### Shorthand Schedules

| Command | Description |
|---------|-------------|
| `@reboot` | Run once at startup |
| `@yearly` | `0 0 1 1 *` — once a year (Jan 1) |
| `@monthly` | `0 0 1 * *` — once a month (1st) |
| `@weekly` | `0 0 * * 0` — once a week (Sunday) |
| `@daily` | `0 0 * * *` — once a day (midnight) |
| `@hourly` | `0 * * * *` — once an hour |

## Examples

### Common Schedules

```
30 2 * * *   /usr/local/bin/backup.sh
0 9 * * 1-5  /opt/report.sh
*/15 * * * *  /usr/bin/health-check.sh
0 0 1 * *    /opt/monthly-cleanup.sh
0 8,17 * * * /opt/notify.sh
```

### Schedule Breakdown

| Command | Description |
|---------|-------------|
| `30 2 * * *` | Daily at 2:30 AM |
| `0 9 * * 1-5` | Weekdays at 9:00 AM |
| `*/15 * * * *` | Every 15 minutes |
| `0 0 1 * *` | First day of month, midnight |
| `0 8,17 * * *` | Daily at 8 AM and 5 PM |

## Environment

### Setting Variables

```
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com
HOME=/home/deploy
* * * * * /opt/myjob.sh
```

### Environment Notes

| Command | Description |
|---------|-------------|
| `SHELL` | Shell used to run commands (default `/bin/sh`) |
| `PATH` | Search path (cron default is minimal) |
| `MAILTO` | Email output to this address (empty = no mail) |
| `HOME` | Home directory for the cron job |

## Logging

### Output & Logging

```
# redirect stdout + stderr to a log file
*/5 * * * * /opt/job.sh >> /var/log/job.log 2>&1
# discard all output
0 3 * * * /opt/job.sh > /dev/null 2>&1
# log only errors
0 3 * * * /opt/job.sh > /dev/null 2>> /var/log/job-err.log
```

### Viewing Cron Logs

```
# Debian / Ubuntu (syslog)
grep CRON /var/log/syslog
# RHEL / CentOS
cat /var/log/cron
# journalctl (systemd)
journalctl -u cron --since "1 hour ago"
```

## Common Schedules

### Everyday Patterns

| Command | Description |
|---------|-------------|
| `0 * * * *` | Every hour on the hour |
| `*/5 * * * *` | Every 5 minutes |
| `*/30 * * * *` | Every 30 minutes |
| `0 0 * * *` | Daily at midnight |
| `0 6 * * 1` | Every Monday at 6 AM |
| `0 0 1,15 * *` | 1st and 15th of month |
| `0 0 * * 5` | Every Friday at midnight |
| `0 0 1 1 *` | Every January 1st |

## crontab Commands

### Managing Crontabs

```
crontab -e               # edit your crontab
crontab -l               # list your crontab
crontab -r               # remove your crontab
crontab -u alice -l      # list another user's (root)
crontab /path/to/file    # install crontab from file
```

### System Crontab Locations

| Command | Description |
|---------|-------------|
| `/etc/crontab` | System-wide crontab (has user field) |
| `/etc/cron.d/` | Drop-in cron files |
| `/etc/cron.daily/` | Scripts run daily |
| `/etc/cron.hourly/` | Scripts run hourly |
| `/etc/cron.weekly/` | Scripts run weekly |
| `/etc/cron.monthly/` | Scripts run monthly |
| `/var/spool/cron/` | Per-user crontab storage |

## Tips

### Best Practices

| Command | Description |
|---------|-------------|
| `Use absolute paths` | Cron PATH is minimal; always use full paths |
| `Redirect output` | Avoid mail floods with `> /dev/null 2>&1` |
| `Lock files` | Use `flock` to prevent overlapping runs |
| `Test first` | Run the command manually before scheduling |
| `Use MAILTO` | Set `MAILTO=""` to suppress all email |
| `Check timezone` | Cron uses system time; verify with `date` |

### Preventing Overlap with flock

```
# only run if not already running
* * * * * /usr/bin/flock -n /tmp/job.lock /opt/job.sh
```
