You write a small backup script on a Tuesday. You run it by hand, and it works. You add it to cron for 2 AM, go to bed, and on Wednesday the backup folder is empty. No error on screen, because there was no screen.
Fact-checked against the official sources on 2 November 2026.
Cron is the Linux tool that runs commands on a timetable. Each user has a crontab, a small file with one line per job: five time fields, then the command. The catch is simple: cron does not run your job inside the terminal you tested in. It starts the job fresh, with its own small set of settings. Most "works by hand, fails in cron" problems come from that gap.
Check this first: is the job even running?
- Run
crontab -land read your line slowly. Five time fields, then the command. - Send the output somewhere you can read it. Add this to the end of the command:
>> /tmp/backup.log 2>&1. The2>&1part sends error messages to the same file as normal output. - Wait for the next run, then open
/tmp/backup.log.
An empty log means the job never ran, so look at the time fields. A log full of errors means it ran and failed, so keep reading.
Check what cron puts in the environment
The environment is the list of settings a program starts with, like HOME (your home folder) and PATH (the folders searched when you type a command name).
The crontab(5) manual page says cron sets a few of these for you: SHELL is set to /bin/sh, and LOGNAME and HOME come from your user's line in /etc/passwd. Your terminal may use a different shell, with your own setup on top. So don't guess what cron sees. Capture it:
* * * * * env > /tmp/cron-env.txt Let that run once, remove the line, then compare /tmp/cron-env.txt with the output of env in your terminal. The difference is your list of suspects.
Use full paths
If PATH in the cron file is shorter than in your terminal, a command like pg_dump or aws may not be found. The fix is plain:
- In your terminal, run
command -v pg_dumpto print the full path. - Use that full path in the script, or set
PATH=on its own line at the top of the crontab. - Use full paths for files too.
backup/means "inside whatever folder the job started in," and cron may start it somewhere else.
Watch out for the percent sign
This one surprises a lot of people. The manual page says an unescaped % in the command part of a cron line is turned into a newline, and everything after the first % is sent to the command as input. So this line breaks:
0 2 * * * tar czf /srv/backup/site-$(date +%F).tgz /srv/site Escape each % with a backslash (date +\%F), or move the command into a script file and call the script from cron.
A small worked example
Say your script is /home/asha/bin/backup.sh and it calls pg_dump. The log from step 2 says pg_dump: not found. You run command -v pg_dump, get /usr/bin/pg_dump, and put that full path in the script. The next 2 AM run writes a file. The whole fix took one log line and one path.
Where this question shows up
Is this real software engineering, or just housekeeping? Both. Small jobs that run quietly at night hold a lot of systems together. At DevGrid Staffing LLC, our services put IT staffing next to secure software work, where security checks are built into every stage of a project. Knowing exactly what runs, when, and as whom belongs to the same careful habit.
One thing to try today
Pick one cron job you own and add >> /tmp/<job-name>.log 2>&1 to it. Tomorrow, read the log.
From the DevGrid Staffing LLC notebook · devgridstaffing.com
