How to Schedule a Cron Job to Run Every 2 Days at 11 PM on Linux Systems


2 views

Cron jobs are typically configured using five time fields (minutes, hours, day of month, month, day of week). For running every 2 days at 11 PM, we need to focus on the day-of-month field (*/2) combined with the specific hour (23).


# Example crontab entry (runs at 11:00 PM every 2 days)
0 23 */2 * * /path/to/your/script.sh

For systems requiring different interval logic, consider these alternatives:


# Method 1: Using day-of-month wildcard
0 23 1-31/2 * * /path/to/script

# Method 2: Date-based execution check
0 23 * * * [ $(($(date +\%d) \% 2)) -eq 0 ] && /path/to/script

When your cron job isn't working:

  • Check system logs: grep CRON /var/log/syslog
  • Verify cron service status: systemctl status cron
  • Test command execution manually
  • Check file permissions and paths
  • Use absolute paths in scripts
  • Redirect output to log files
  • Include error handling in scripts
  • Consider using systemd timers for complex schedules

# Example with logging
0 23 */2 * * /usr/bin/python3 /opt/scripts/nightly.py >> /var/log/nightly.log 2>&1

For servers in different time zones:


# Set system time zone
sudo timedatectl set-timezone America/New_York

# Or specify TZ in crontab
TZ=UTC
0 23 */2 * * /path/to/script

Cron jobs on CentOS/RHEL systems follow a specific time notation format:

* * * * * command_to_execute
- - - - -
| | | | |
| | | | +----- Day of week (0-6) (Sunday=0)
| | | +------- Month (1-12)
| | +--------- Day of month (1-31)
| +----------- Hour (0-23)
+------------- Minute (0-59)

For running a job at 11 PM every two days, we have several approaches:

Method 1: Using Day-of-Month Increment

0 23 */2 * * /path/to/your/script.sh

This will run at 11 PM on even-numbered days (2nd, 4th, etc.). Note that months with 31 days will see consecutive executions on 30th and 31st.

Method 2: Date-Based Conditional Execution

0 23 * * * [ $(($(date +\%d)\%2)) -eq 0 ] && /path/to/your/script.sh

The arithmetic operation checks if current day is even before executing.

Method 3: Using Systemd Timers (Modern Alternative)

# /etc/systemd/system/your-service.timer
[Unit]
Description=Run every 48 hours at 11PM

[Timer]
OnCalendar=*-*-* 23:00:00
AccuracySec=1h
Persistent=true
Unit=your-service.service

[Install]
WantedBy=timers.target

If your scheduled job isn't running as expected:

  • Verify cron service status: systemctl status crond
  • Check mail for cron output: mail -u your_user
  • Redirect output to log file: 0 23 */2 * * /path/script.sh >> /var/log/cron.log 2>&1
  • Confirm script permissions: chmod +x /path/script.sh
  • Test environment variables: Cron runs with minimal env - specify full paths

For complex scheduling requirements, consider a state file approach:

0 23 * * * /usr/bin/flock -n /tmp/yourjob.lock /bin/bash -c '[[ -f /var/run/yourjob.flag ]] && rm /var/run/yourjob.flag || (touch /var/run/yourjob.flag && /path/script.sh)'

This creates a toggle mechanism that alternates execution days while preventing overlapping runs.