When setting up a cron job to run on the first day of each month, you need to understand the five time fields in crontab:
* * * * * command_to_execute ┬ ┬ ┬ ┬ ┬ │ │ │ │ └── Day of week (0-6) (0 is Sunday) │ │ │ └──── Month (1-12) │ │ └────── Day of month (1-31) │ └──────── Hour (0-23) └────────── Minute (0-59)
For a job that runs at midnight on the first day of every month:
0 0 1 * * /path/to/your/script.sh
This breaks down as:
- Minute: 0 (top of the hour)
- Hour: 0 (midnight)
- Day of month: 1 (first day)
- Month: * (every month)
- Day of week: * (ignored when day of month is specified)
1. Environment Variables
Cron jobs run with a minimal environment. Always specify full paths:
0 0 1 * * /usr/bin/python3 /home/user/scripts/monthly_report.py
2. Permission Issues
Ensure your script is executable:
chmod +x /path/to/your/script.sh
3. Logging for Debugging
Redirect output to a log file:
0 0 1 * * /path/to/script.sh >> /var/log/monthly_job.log 2>&1
Using @monthly Special String
Some cron implementations support:
@monthly /path/to/script.sh
This runs at midnight on the first day of each month.
Systemd Timers (Modern Linux Systems)
Create a timer unit file:
[Unit] Description=Monthly job [Timer] OnCalendar=*-*-01 00:00:00 Persistent=true [Install] WantedBy=timers.target
Check system logs to confirm execution:
grep CRON /var/log/syslog
Or test with a temporary job that runs sooner:
* * * * * /path/to/test_script.sh
#!/usr/bin/env python3 import datetime import sys try: # Your monthly tasks here print(f"Monthly job executed at {datetime.datetime.now()}") except Exception as e: print(f"Error: {str(e)}", file=sys.stderr) sys.exit(1)
Configure in crontab:
0 0 1 * * /usr/bin/python3 /path/to/monthly.py >> /var/log/monthly.log 2>&1
Cron jobs are scheduled using a specific syntax with five time fields followed by the command to execute:
* * * * * command_to_execute ┬ ┬ ┬ ┬ ┬ │ │ │ │ └── Day of the week (0 - 6) (Sunday=0) │ │ │ └──── Month (1 - 12) │ │ └────── Day of the month (1 - 31) │ └──────── Hour (0 - 23) └────────── Minute (0 - 59)
To run a job on the first day of every month at midnight, use:
0 0 1 * * /path/to/your/script.sh
This breaks down as:
- Minute: 0 (top of the hour)
- Hour: 0 (midnight)
- Day: 1 (first day of month)
- Month: * (every month)
- Day of week: * (ignored when day of month is specified)
Here are some common use cases with complete examples:
1. Database Backup
0 0 1 * * /usr/bin/mysqldump -u root -pPASSWORD database_name > /backups/db_$(date +\%Y\%m\%d).sql
2. Log Rotation
0 0 1 * * /usr/sbin/logrotate /etc/logrotate.d/myapp
3. Monthly Report Generation
0 0 1 * * /usr/bin/python3 /scripts/generate_monthly_report.py
If your cron job isn't working:
- Check system logs:
grep CRON /var/log/syslog
- Verify the command works when run manually
- Ensure the script has execute permissions
- Use absolute paths in your commands
- Check the user's environment variables
For more complex scheduling needs:
# Run on first weekday of month (Mon-Fri) 0 0 1-7 * * [ "$(date +\%u)" -le 5 ] && /path/to/command # Run on first Monday of month 0 0 1-7 * * [ "$(date +\%u)" -eq 1 ] && /path/to/command