crontabSchedule recurring jobs with cron
crontab installs, lists and removes your personal cron table: lines of five time fields plus a command that the cron daemon runs on schedule, such as backups at 02:00 or health checks every 5 minutes. Most cron bugs come from cron's minimal environment, not from the schedule.
crontab [-u USER] { -e | -l | -r | FILE }Schedule a health check every 5 minutes and a backup at 02:00 for your user, from a file you keep in git.
*/5Minute field (0-59). */5 = every 5 minutes: 0, 5, 10... 55.
The cron daemon (cron on Debian/Ubuntu, crond from cronie on RHEL and Amazon Linux) wakes up once a minute. It reads user crontabs from /var/spool/cron/crontabs/<user> (/var/spool/cron/<user> on RHEL), plus /etc/crontab and /etc/cron.d/*, whose lines have an extra user field. It re-reads a file only when the spool directory's mtime changes. You can't write the spool directly: crontab is setgid crontab, checks /etc/cron.allow and cron.deny, validates your syntax, then installs the file. For each line matching the current minute, cron forks, switches to the user and runs /bin/sh -c 'command' with a minimal environment: HOME, LOGNAME, SHELL=/bin/sh and PATH=/usr/bin:/bin. Your .bashrc and exported variables are not loaded. Output is mailed to MAILTO through the local MTA, and with no MTA it's discarded. When both day-of-month and day-of-week are restricted, a job runs when either matches. Every run is logged as 'CRON[pid]: (user) CMD (...)'.
crontab only installs a file; the cron daemon wakes every minute, matches lines and runs them with a bare environment.
Your editor saves a temp file. crontab checks the five fields of every line and, if they're valid, writes /var/spool/cron/crontabs/kunal. A bad line means nothing is installed.
-eEdit your crontab in $EDITOR; it's validated and installed on save-lPrint your crontab-rRemove your whole crontab, with no confirmation-iWith -r: ask before removing (Debian/RHEL)FILEReplace your crontab with the contents of FILE-u USERAct on another user's crontab (root only)*/NEvery N units: */15 in the minute field = every 15 minA-B, A,BRanges and lists: 1-5 = Mon-Fri, 0,30 = on the hour and half hour@reboot, @daily, @hourlyShortcuts: once at boot, 0 0 * * *, 0 * * * *MAILTO=Line at the top: where output goes (empty = nowhere)PATH=Line at the top: give jobs a real PATH0 2 * * * backup.shcron's PATH is /usr/bin:/bin and its working directory is $HOME, so relative commands and tools in /usr/local/bin aren't found.
0 2 * * * /home/kunal/bin/backup.sh >> /home/kunal/logs/backup.log 2>&10 0 * * * tar czf /backup/$(date +%F).tgz /data% is special in crontab: it ends the command and the rest becomes stdin. The job runs 'tar czf /backup/$(date +' and fails.
0 0 * * * tar czf /backup/$(date +\%F).tgz /data # or move it into a script0 9 1 * 1 report.sh, meaning 'the first Monday of the month'When day-of-month and day-of-week are both set, cron runs on either: the 1st of every month AND every Monday.
0 9 1-7 * * [ "$(date +\%u)" = 1 ] && /opt/report.shScheduling 0 9 * * * and expecting 09:00 local timecron uses the server's timezone, which is UTC on almost every cloud instance.
Check timedatectl; convert to UTC (or use CRON_TZ= with cronie, or a systemd timer with a timezone)Running a 10-minute job every 5 minutescron starts a new copy whether or not the last one finished; runs overlap and fight over the same files.
*/5 * * * * flock -n /tmp/sync.lock /opt/sync.shTry these on a Linux machine of your own. Each task has a hint and a solution.
Install the example crontab from ~/crontab.example, then list your crontab to confirm.
Add a job that appends the date to ~/logs/tick.log every minute. Wait a minute and check it ran.
Find out what environment cron gives your jobs.
Find the system cron job in /etc/cron.d that deletes old app logs, and say when it runs.
Back up your crontab to ~/crontab.bak, then remove all your cron jobs.
crontabSchedule recurring jobs with cron
crontab installs, lists and removes your personal cron table: lines of five time fields plus a command that the cron daemon runs on schedule, such as backups at 02:00 or health checks every 5 minutes. Most cron bugs come from cron's minimal environment, not from the schedule.
crontab [-u USER] { -e | -l | -r | FILE }Schedule a health check every 5 minutes and a backup at 02:00 for your user, from a file you keep in git.
*/5Minute field (0-59). */5 = every 5 minutes: 0, 5, 10... 55.
The cron daemon (cron on Debian/Ubuntu, crond from cronie on RHEL and Amazon Linux) wakes up once a minute. It reads user crontabs from /var/spool/cron/crontabs/<user> (/var/spool/cron/<user> on RHEL), plus /etc/crontab and /etc/cron.d/*, whose lines have an extra user field. It re-reads a file only when the spool directory's mtime changes. You can't write the spool directly: crontab is setgid crontab, checks /etc/cron.allow and cron.deny, validates your syntax, then installs the file. For each line matching the current minute, cron forks, switches to the user and runs /bin/sh -c 'command' with a minimal environment: HOME, LOGNAME, SHELL=/bin/sh and PATH=/usr/bin:/bin. Your .bashrc and exported variables are not loaded. Output is mailed to MAILTO through the local MTA, and with no MTA it's discarded. When both day-of-month and day-of-week are restricted, a job runs when either matches. Every run is logged as 'CRON[pid]: (user) CMD (...)'.
crontab only installs a file; the cron daemon wakes every minute, matches lines and runs them with a bare environment.
Your editor saves a temp file. crontab checks the five fields of every line and, if they're valid, writes /var/spool/cron/crontabs/kunal. A bad line means nothing is installed.
-eEdit your crontab in $EDITOR; it's validated and installed on save-lPrint your crontab-rRemove your whole crontab, with no confirmation-iWith -r: ask before removing (Debian/RHEL)FILEReplace your crontab with the contents of FILE-u USERAct on another user's crontab (root only)*/NEvery N units: */15 in the minute field = every 15 minA-B, A,BRanges and lists: 1-5 = Mon-Fri, 0,30 = on the hour and half hour@reboot, @daily, @hourlyShortcuts: once at boot, 0 0 * * *, 0 * * * *MAILTO=Line at the top: where output goes (empty = nowhere)PATH=Line at the top: give jobs a real PATH0 2 * * * backup.shcron's PATH is /usr/bin:/bin and its working directory is $HOME, so relative commands and tools in /usr/local/bin aren't found.
0 2 * * * /home/kunal/bin/backup.sh >> /home/kunal/logs/backup.log 2>&10 0 * * * tar czf /backup/$(date +%F).tgz /data% is special in crontab: it ends the command and the rest becomes stdin. The job runs 'tar czf /backup/$(date +' and fails.
0 0 * * * tar czf /backup/$(date +\%F).tgz /data # or move it into a script0 9 1 * 1 report.sh, meaning 'the first Monday of the month'When day-of-month and day-of-week are both set, cron runs on either: the 1st of every month AND every Monday.
0 9 1-7 * * [ "$(date +\%u)" = 1 ] && /opt/report.shScheduling 0 9 * * * and expecting 09:00 local timecron uses the server's timezone, which is UTC on almost every cloud instance.
Check timedatectl; convert to UTC (or use CRON_TZ= with cronie, or a systemd timer with a timezone)Running a 10-minute job every 5 minutescron starts a new copy whether or not the last one finished; runs overlap and fight over the same files.
*/5 * * * * flock -n /tmp/sync.lock /opt/sync.shTry these on a Linux machine of your own. Each task has a hint and a solution.
Install the example crontab from ~/crontab.example, then list your crontab to confirm.
Add a job that appends the date to ~/logs/tick.log every minute. Wait a minute and check it ran.
Find out what environment cron gives your jobs.
Find the system cron job in /etc/cron.d that deletes old app logs, and say when it runs.
Back up your crontab to ~/crontab.bak, then remove all your cron jobs.