In Ubuntu systems, the /etc/cron.daily/
directory is part of the standard cron setup. However, there's a crucial detail many admins miss: scripts here don't run via traditional cron but through anacron
, which has different scheduling logic.
# Check if anacron is installed (Ubuntu server minimal might not have it) dpkg -l | grep anacron # Verify cron.daily execution in syslog (note the different log pattern) grep -i cron.daily /var/log/syslog | tail -n 5
Common failure patterns include:
- Missing execute permissions:
chmod +x /etc/cron.daily/your_script
- Script dependencies not available in restricted cron environment
- Output not being captured (scripts should handle logging explicitly)
#!/bin/bash # Proper cron.daily script template LOGFILE=/var/log/custom_daily.log { echo "$(date) - Starting daily job" # Main logic here /usr/bin/your_command --some-flag echo "$(date) - Job completed" } >> "$LOGFILE" 2>&1
For modern Ubuntu systems (18.04+), consider using systemd timers instead:
# Example systemd timer unit [Unit] Description=Daily maintenance job [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target
- Verify script has execute permission (+x)
- Test script runs manually:
sudo /etc/cron.daily/your_script
- Check
/var/mail/root
for error messages - Confirm anacron is active:
systemctl status anacron
In Ubuntu systems, the /etc/cron.daily/
directory is part of the anacron system designed for systems that aren't running 24/7. Contrary to popular assumption, scripts placed here don't execute through the standard cron daemon but are instead managed by run-parts
via /etc/crontab
:
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd /amp;& run-parts --report /etc/cron.monthly )
Several factors could prevent your script from executing:
- File permissions: Scripts must be executable (
chmod +x /etc/cron.daily/your_script
) - Naming conventions: Avoid special characters and extensions (.sh typically not needed)
- Shebang line: Missing interpreter directive (e.g.,
#!/bin/bash
) - Path issues: Absolute paths should be used for commands
Create a test script with explicit error output:
#!/bin/bash
# /etc/cron.daily/testjob
echo "$(date) - Test job started" >> /var/log/cron_test.log
/usr/bin/your_command >> /var/log/cron_test.log 2>&1
echo "$(date) - Exit status: $?" >> /var/log/cron_test.log
Then force execution to test:
sudo run-parts --verbose /etc/cron.daily
For more predictable scheduling, consider using root's crontab:
sudo crontab -e
# Add this line for daily execution at 2:30 AM
30 2 * * * /path/to/your/script.sh
Modern Ubuntu systems can use systemd timers for better logging:
# /etc/systemd/system/myjob.timer
[Unit]
Description=Run myjob daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/myjob.service
[Unit]
Description=My custom job
[Service]
Type=oneshot
ExecStart=/path/to/your/script.sh
Enable with:
sudo systemctl enable --now myjob.timer