67

I prefer to stick scheduled tasks in /etc/crontab so I can see at a glance what's scheduled to run, regardless of which user the task runs as.

The only gotcha is that the format isn't validated on save, unlike crontab -e - so a stray character can quietly break the entire cron.

Is there a way to validate the /etc/crontab format before/after save?

Ben K.
  • 2,489

7 Answers7

48

The only reliable way I found is to check the log.

cron checks /etc/crontab every minute, and logs a message indicating that it has reloaded it, or that it found an error.

So after editing, run this:

sleep 60; grep crontab /var/log/syslog | tail

Or, to not wait a full minute, but only until the next minute + 5 seconds:

sleep $(( 60 - $(date +%S) + 5 )) && grep cron /var/log/syslog | tail

Example output with an error:

Jan  9 19:10:57 r530a cron[107258]: Error: bad minute; while reading /etc/crontab
Jan  9 19:10:57 r530a cron[107258]: (*system*) ERROR (Syntax error, this crontab file will be ignored)

Good output:

Jan  9 19:19:01 r530a cron[107258]: (*system*) RELOAD (/etc/crontab)

That's on Debian 8. On other systems, cron might log to a different file.

(I thought I could avoid hunting for the right log file by using systemd's journalctl -u cron, but that didn't show me these log entries, and actually seems to have stopped logging cron events 2 days ago for some reason)

mivk
  • 4,924
16

Another more recent solution is the python script chkcrontab

11

Wicked cool shell scripts has a shell script that validates crontab files.

You can get the zip archive containing the script here

The script is called verifycron

Gohu
  • 121
6

I found this cool solution here: https://crontab.guru

It doesn't just validate the crontab, it tells you explicitly what and when the crontab will run, and highlights where errors are.

JDS
  • 2,678
2

This has worked the best for me:

systemctl restart cron; journalctl -u cron --lines 10

Forcing the restart ensures that cron checks the syntax immediately, instead of waiting 60 seconds. If there are any errors, journalctl will show them.

0

Try running crontab -T path/to/crontab.

Note that crontab -T may not be available in Debian-based distributions. It's available in Arch Linux.

If you want to automatically do it before/after, you can write your own visudo style wrapper, such as

$EDITOR /etc/crontab
crontab -T /etc/crontab

Personally, since breaking the crontab is not as bad as breaking sudoers, I think it's fine to just print the message, but you could also everything to a tempfile if you wanted.

0

Tailing the logs is the best solution I feel, as pointed out by @mivk in their answer.

journalctl is a good option too:

vedant@zebronics:~$ journalctl -u cron.service 
... <hit shift+G to goto last line>
Nov 03 10:33:01 zebronics cron[627]: (*system*) RELOAD (/etc/crontab)

(Hit shift+G to go the latest line in journal)