Cron tools › Build / Generate
Crontab line builder
Put in a schedule and the command you would type in a terminal. The builder writes the crontab line a careful admin would — no overlapping runs, output captured, a time limit — escapes the characters cron treats specially, and explains every piece.
Safety options
Environment
Your crontab lines
What each piece does
| Piece | What it does |
|---|
When it runs
How to build a crontab line
- Enter the schedule, or click a preset. Anything the parser accepts works, including
@dailyand@reboot. - Type the command exactly as you would run it in a terminal — do not escape anything yourself.
- Tick the safety options you want. Overlap protection and a log file are on by default because they prevent the two most common cron incidents: runs piling up, and failures nobody sees.
- Add environment lines if the job needs them —
PATHfor programs outside/usr/bin,MAILTOfor where output goes. - Copy the lines into
crontab -e(leave User empty) or into a file in/etc/cron.d/(fill it in). Keep a newline after the last line.
Why every % becomes \%
In a crontab, % in the command part is not a percent sign. Cron turns the first unescaped % into a newline and sends everything after it
to the command's standard input. So tar czf /backup/$(date +%F).tgz /srv — fine in a terminal — reaches the shell as tar czf /backup/$(date +,
a syntax error, and the job fails with a confusing message in cron's mail. Written as date +\%F it works. The builder escapes every %
in the command, the log path and the $((RANDOM % 300)) of the random delay; a \% you already typed is left alone.
What the options protect against
| Option | Adds | Protects against |
|---|---|---|
| Overlap lock | flock -n /tmp/job.lock … | A slow run still going when the next one starts, then two, then ten. |
| Log file | >> /var/log/job.log 2>&1 | Errors vanishing into a mailbox nobody reads. |
| Time limit | timeout 30m … | A hung job holding the lock forever, so no later run can start. |
| Directory | cd /srv/app && … | Relative paths resolving against the user's home directory. |
| nice | nice -n 10 … | A batch job slowing down the service on the same machine. |
| Random delay | sleep $((RANDOM % 300)) && … | Every server in a fleet hitting the same backend in the same second. For a fixed per-host offset instead, use the stagger generator. |
| PATH | PATH=/usr/local/bin:… | "command not found" because cron's default PATH is minimal. |
Before installing a whole file, run it through the crontab checker: it catches unescaped %, a missing final newline and jobs scheduled in the hour that daylight saving time skips.
FAQ
Do I need the user field?
Only in the system crontab (/etc/crontab) and files in /etc/cron.d/, which have a sixth column naming the user to run as.
A personal crontab edited with crontab -e has no user field — putting one there makes cron treat the name as the command.
Why did it add SHELL=/bin/bash?
The random delay uses $RANDOM, which is a bash feature; cron runs commands with /bin/sh unless the crontab sets SHELL.
The builder also warns when your own command uses bash-only syntax such as [[ … ]], arrays or &> without bash selected.
Does CRON_TZ work on Ubuntu?
No. CRON_TZ is a cronie feature (Fedora, RHEL, Arch). Debian and Ubuntu cron have no per-user time zones; there, TZ only changes the time zone the command sees, not when it runs.
Why wrap the command in sh -c when a lock or time limit is on?
flock, timeout and nice run one program. If your command has a pipe or &&, only the part before it would be
locked or timed. Wrapping it in sh -c '…' (or bash -c) makes the whole command one program.