如何编写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
脚本使用说明
- 修改配置区:将
TASK_CMD、START_TIME、END_TIME、PID_FILE替换为你的实际参数 - 赋予执行权限:
chmod +x /path/to/your-script.sh - 设置开机启动:
- 在Linux Mint中打开「启动应用程序」(Startup Applications)
- 添加新项,命令填写
/path/to/your-script.sh,名称和描述自定义
- 可选:Cron备份检查(防止脚本意外退出):
- 执行
crontab -e添加以下内容,每小时检查一次脚本状态,若未运行则重启:0 * * * * /path/to/your-script.sh
- 执行
关键细节说明
- 时间戳比较:用
date命令将时间转换为秒级时间戳,避免字符串比较的时区/格式问题 - PID文件机制:防止同一任务被重复启动,同时自动清理进程意外退出后残留的无效PID文件
- at命令定时停止:相比
sleep,at命令不受机器休眠/脚本退出的影响,能确保任务在指定时间停止 - 命令行参数支持:脚本通过
stop/start参数接受外部调用,方便at或Cron触发
内容的提问来源于stack exchange,提问作者user18003991
相关产品推荐
相关产品推荐

