You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Bash脚本实现开机启动+定时段运行任务并接入Cron

解决方案:Linux Mint 21 定时启停任务脚本

核心逻辑说明

脚本实现以下三个核心行为:

  • 开机时若当前时间处于[启动时间, 结束时间]区间内,立即启动任务
  • 开机时若当前时间早于启动时间,等待到启动时间再启动任务
  • 无论何时启动任务,都确保在结束时间自动停止任务
  • 内置重复启动防护机制

可直接使用的Bash脚本

#!/bin/bash

# -------------------------- 配置区 --------------------------
# 要启动的任务命令(替换为你的软件包启动命令)
TASK_CMD="/usr/bin/your-application"
# 每日启动时间(格式:HH:MM)
START_TIME="09:00"
# 每日结束时间(格式:HH:MM)
END_TIME="18:00"
# 用于记录任务PID的文件路径(避免重复启动)
PID_FILE="/var/run/your-task.pid"
# -----------------------------------------------------------

# 将时间转换为当天的时间戳(秒数)
convert_to_timestamp() {
    date -d "$1" +%s
}

# 获取当前时间戳
CURRENT_TIMESTAMP=$(date +%s)
# 获取今日启动、结束时间的时间戳
TODAY_START=$(convert_to_timestamp "$START_TIME")
TODAY_END=$(convert_to_timestamp "$END_TIME")
# 获取明日启动时间的时间戳
TOMORROW_START=$(convert_to_timestamp "tomorrow $START_TIME")

# 检查任务是否已在运行
is_task_running() {
    if [ -f "$PID_FILE" ]; then
        local pid=$(cat "$PID_FILE")
        if ps -p "$pid" > /dev/null 2>&1; then
            return 0
        else
            # PID文件存在但进程已死,删除无效文件
            rm -f "$PID_FILE"
        fi
    fi
    return 1
}

# 启动任务的函数
start_task() {
    if is_task_running; then
        echo "任务已在运行,无需重复启动"
        return
    fi
    echo "启动任务:$TASK_CMD"
    # 后台启动任务并记录PID
    $TASK_CMD &
    echo $! > "$PID_FILE"
    # 设置定时停止任务:用at命令在结束时间执行停止操作
    echo "$0 stop" | at "$END_TIME"
}

# 停止任务的函数
stop_task() {
    if is_task_running; then
        local pid=$(cat "$PID_FILE")
        echo "停止任务(PID:$pid)"
        kill "$pid"
        rm -f "$PID_FILE"
        # 取消可能存在的未执行的启动任务(如果有的话)
        atq | grep -v "stop" | grep "$0 start" | awk '{print $1}' | xargs atrm 2>/dev/null
    else
        echo "任务未运行,无需停止"
    fi
}

# 根据命令行参数执行对应操作(用于at调用)
if [ "$1" = "stop" ]; then
    stop_task
    exit 0
elif [ "$1" = "start" ]; then
    start_task
    exit 0
fi

# 主逻辑:判断当前时间所处阶段
if [ "$CURRENT_TIMESTAMP" -ge "$TODAY_START" ] && [ "$CURRENT_TIMESTAMP" -le "$TODAY_END" ]; then
    # 当前处于时间段内,立即启动任务
    start_task
elif [ "$CURRENT_TIMESTAMP" -lt "$TODAY_START" ]; then
    # 当前早于启动时间,等待到启动时间再启动
    WAIT_SECONDS=$((TODAY_START - CURRENT_TIMESTAMP))
    echo "当前时间早于启动时间,等待$WAIT_SECONDS秒后启动任务"
    sleep "$WAIT_SECONDS"
    start_task
else
    # 当前晚于结束时间,等待到明日启动时间再启动
    WAIT_SECONDS=$((TOMORROW_START - CURRENT_TIMESTAMP))
    echo "当前时间晚于结束时间,等待$WAIT_SECONDS秒后启动任务"
    sleep "$WAIT_SECONDS"
    start_task
fi

脚本使用说明

  1. 修改配置区:将TASK_CMD、START_TIME、END_TIME、PID_FILE替换为你的实际参数
  2. 赋予执行权限:
    chmod +x /path/to/your-script.sh
    
  3. 设置开机启动:
    • 在Linux Mint中打开「启动应用程序」(Startup Applications)
    • 添加新项,命令填写/path/to/your-script.sh,名称和描述自定义
  4. 可选:Cron备份检查(防止脚本意外退出):
    • 执行crontab -e添加以下内容,每小时检查一次脚本状态,若未运行则重启:
      0 * * * * /path/to/your-script.sh
      

关键细节说明

  • 时间戳比较:用date命令将时间转换为秒级时间戳,避免字符串比较的时区/格式问题
  • PID文件机制:防止同一任务被重复启动,同时自动清理进程意外退出后残留的无效PID文件
  • at命令定时停止:相比sleep,at命令不受机器休眠/脚本退出的影响,能确保任务在指定时间停止
  • 命令行参数支持:脚本通过stop/start参数接受外部调用,方便at或Cron触发

内容的提问来源于stack exchange,提问作者user18003991

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:10:42