System Cron Pitfalls

System Cron Directories and Environment Traps

/etc/crontab and files in /etc/cron.d/ add a sixth field, the user to run as; version your server's jobs there. Scripts in /etc/cron.daily (and .hourly, .weekly, .monthly) run through run-parts at 06:25 on Ubuntu 225 , or through anacron, which catches up missed runs, where it is installed. run-parts silently skips names containing a dot, so db-backup.sh never runs; check with run-parts --test.

Jobs run under /bin/sh without your ~/.profile. Three appended lines show the traps: env > /tmp/cron-env.txt, sitemap-build >> /tmp/sitemap.log 2>&1 and date +%F >> /tmp/today.log.

What cron did with the three trap jobsShell
grep -E '^(PATH|SHELL)=' /tmp/cron-env.txt; cat /tmp/sitemap.log
sudo journalctl -u cron --since -1min -o cat -g 'date \+\)|MTA'
Output
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:...
SHELL=/bin/sh
/bin/sh: 1: sitemap-build: not found
(dev) CMD (date +)
(CRON) info (No MTA installed, discarding output)

PATH comes from /etc/environment and lacks ~/bin. The unescaped % became a newline, cutting the command to date +, and its output, meant for mail, was discarded. Use absolute paths, write \%, redirect 2>&1, and wrap long jobs in flock -n /run/lock/job.lock so overlapping runs are skipped.