能否实现每50小时执行一次Cron任务?技术实现咨询
Great question! Cron's syntax is built around calendar-based scheduling (minutes, hours, days, etc.), which means it doesn't support direct intervals longer than 24 hours—since 50 hours crosses multiple days and doesn't align neatly with daily/weekly cycles. But don't worry, there are two reliable workarounds to get this done.
Option 1: Cron + Time-Check Script
This approach uses a simple shell script to track when the task last ran, and an hourly Cron job to trigger the script. The script only executes your actual command if 50 hours have passed since the last run.
Create the check-and-run script (e.g.,
run_every_50h.sh):#!/bin/bash # Path to store the timestamp of the last execution LAST_RUN_LOG="/var/log/my_task_last_run.txt" CURRENT_TIMESTAMP=$(date +%s) FIFTY_HOURS_IN_SECONDS=$((50 * 60 * 60)) # If the log doesn't exist, run the task and initialize the log if [ ! -f "$LAST_RUN_LOG" ]; then /path/to/your/actual_task.sh echo "$CURRENT_TIMESTAMP" > "$LAST_RUN_LOG" exit 0 fi # Calculate time since last run LAST_RUN_TIMESTAMP=$(cat "$LAST_RUN_LOG") TIME_ELAPSED=$((CURRENT_TIMESTAMP - LAST_RUN_TIMESTAMP)) # Run the task if 50 hours have passed if [ "$TIME_ELAPSED" -ge "$FIFTY_HOURS_IN_SECONDS" ]; then /path/to/your/actual_task.sh echo "$CURRENT_TIMESTAMP" > "$LAST_RUN_LOG" fiMake the script executable:
chmod +x /path/to/run_every_50h.shAdd a Cron job to run the script hourly (or every 30 minutes for more precision):
Open your Cron tab withcrontab -eand add:0 * * * * /path/to/run_every_50h.sh
Option 2: Systemd Timer (Recommended for Modern Linux)
If your system uses systemd (most distros like Ubuntu, Debian, RHEL do), this is a cleaner solution. Systemd timers support relative time intervals directly, so you don't need to handle timestamp tracking manually.
Create a service file (e.g.,
my-50hour-task.service) in/etc/systemd/system/:[Unit] Description=Task that runs every 50 hours [Service] ExecStart=/path/to/your/actual_task.sh # Add any other service options you need (e.g., User, WorkingDirectory)Create the corresponding timer file (e.g.,
my-50hour-task.timer) in the same directory:[Unit] Description=Timer to trigger the 50-hour task [Timer] # Run 50 hours after the last time the service was activated OnUnitActiveSec=50h # If the system was off when the task should have run, run it on boot Persistent=true [Install] WantedBy=timers.targetEnable and start the timer:
sudo systemctl daemon-reload sudo systemctl start my-50hour-task.timer sudo systemctl enable my-50hour-task.timer
To verify the timer is active, run sudo systemctl list-timers.
Why Cron Can't Do This Directly
Cron's syntax relies on fixed calendar values (0-23 for hours, 1-31 for days, etc.). Since 50 hours equals 2 days and 2 hours, there's no way to write a single Cron expression that accounts for the shifting hour of day each cycle (e.g., first run at 00:00, next at 02:00 two days later, then 04:00 two days after that, and so on). The workarounds above avoid this limitation by either tracking time manually or using a system that supports relative intervals.
Hope this helps you get your task scheduled perfectly! Let me know if you need help debugging any part of these setups.
内容的提问来源于stack exchange,提问作者mgurcan

