How to Configure Cron Jobs with Time-Based Conditions (10pm-2am vs Regular Intervals)


11 views

When working with cron jobs, we often encounter scenarios where we need different execution frequencies based on time windows. The specific requirement here involves:

  • Every minute execution between 10 PM - 2 AM
  • Every 10 minutes execution outside this window

Standard cron syntax doesn't directly support:

* * * * * command # Runs every minute
*/10 * * * * command # Runs every 10 minutes

The challenge is combining these with time conditions.

Solution 1: Time-Check Wrapper Script

Create a shell script that checks the current time before execution:

#!/bin/bash
HOUR=$(date +%H)
if (( 22 <= 10#$HOUR || 10#$HOUR < 2 )); then
    # Run minute job
    your_command
else
    # Only run if minute is divisible by 10
    MINUTE=$(date +%M)
    if (( 10#$MINUTE % 10 == 0 )); then
        your_command
    fi
fi

Then set your cron to run every minute:

* * * * * /path/to/wrapper_script.sh

Solution 2: Dual Cron Entries

Use two separate cron entries with time restrictions:

# Every minute between 10pm-2am
* 22-23,0-1 * * * /path/to/command

# Every 10 minutes other times
*/10 2-21 * * * /path/to/command

For modern Linux systems, consider systemd timers:

[Unit]
Description=Time-based job runner

[Timer]
OnCalendar=*-*-* 22,23,00,01:00..59:00
OnCalendar=*-*-* 02..21:0/10:00

[Install]
WantedBy=timers.target

Important considerations:

  • Timezone awareness (always use UTC for servers)
  • Day boundary handling (22-23 and 0-1 covers the 4-hour window)
  • Command idempotency (ensure safe multiple executions)

For the wrapper script approach:

  • Minimal overhead for time checks
  • No process spawning during off-peak minutes
  • Simpler monitoring (single cron entry)

When managing cron jobs, there are scenarios where you need different execution frequencies based on the time of day. For instance, you might want a job to run:

  • Every minute during specific hours (e.g., 10 PM to 2 AM).
  • Every 10 minutes outside that window.

Cron syntax doesn't natively support conditional intervals, but there are workarounds.

The simplest way is to define two cron entries:

# Run every minute between 10 PM and 2 AM
* 22,23,0,1 * * * /path/to/your/script.sh

# Run every 10 minutes outside 10 PM - 2 AM
*/10 2-21 * * * /path/to/your/script.sh

Note: This assumes the script is idempotent (running it multiple times won't cause issues).

Alternatively, handle the timing logic within the script itself. Here’s a Bash example:

#!/bin/bash

current_hour=$(date +%H)

if [[ $current_hour -ge 22 || $current_hour -lt 2 ]]; then
  # Logic for 10 PM - 2 AM (every minute)
  echo "Running in high-frequency mode"
else
  # Logic for other times (every 10 minutes)
  echo "Running in low-frequency mode"
fi

Then set the cron to run every minute:

* * * * * /path/to/your/script.sh

For more granular control, use a wrapper script with sleep:

#!/bin/bash

while true; do
  current_hour=$(date +%H)
  if [[ $current_hour -ge 22 || $current_hour -lt 2 ]]; then
    interval=60  # 1 minute
  else
    interval=600 # 10 minutes
  fi
  /path/to/your/actual_script.sh
  sleep $interval
done

Run this script at startup or via cron:

@reboot /path/to/your/wrapper_script.sh

Remember:

  • Cron uses the system’s timezone. Verify it matches your requirements.
  • For cross-day ranges (like 10 PM to 2 AM), split the logic correctly (e.g., 22-23,0-1).

For complex schedules, consider:

  • systemd timers: More flexible than cron.
  • Jenkins or other CI/CD tools: If the job is part of a pipeline.