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

如何在系统启动20秒后运行bash脚本?或实现程序启动后执行脚本

嗨Elias,针对你的问题,我整理了几个实用的方案,帮你搞定脚本在系统启动时的执行时机问题~

方案1:快速实现固定延迟启动

这是你最初想到的思路,操作起来很简单,有两种方式可选:

  • 修改脚本本身:直接在task.sh的开头加入延迟命令,让脚本先等一会儿再执行核心逻辑:
#!/bin/bash
sleep 30  # 延迟30秒,可根据实际情况调整时长
# 以下是你的原有脚本内容
stop_target_program
mount_raspberry_pi
start_target_program
  • 用systemd服务管理延迟:如果不想修改脚本,可以通过systemd的前置指令来实现延迟。先创建一个task.service文件,放到/etc/systemd/system/目录下:
[Unit]
Description=Run task.sh after system boot
After=multi-user.target  # 确保在系统进入多用户环境后执行

[Service]
Type=oneshot  # 表示服务只执行一次
ExecStartPre=/bin/sleep 30  # 执行脚本前先睡30秒
ExecStart=/path/to/your/task.sh  # 替换成你实际的脚本路径
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

然后执行以下命令启用服务:

sudo systemctl daemon-reload
sudo systemctl enable task.service

这种方式的缺点是延迟时间固定,如果目标程序启动速度不稳定,可能会出现脚本执行时程序还没起来,或者白白浪费等待时间的情况。

方案2:更可靠的「等待目标程序启动后再执行」

你担心的「程序重启后脚本会再次触发重启」其实是可以避免的——只要让脚本只在系统启动时执行一次,而不是程序每次启动都触发。用systemd的oneshot类型服务就能做到这一点,同时我们可以让脚本主动等待目标程序完全启动后再操作。

方式A:脚本内轮询等待进程

修改你的task.sh,加入等待逻辑,直到目标程序运行起来再执行后续操作:

#!/bin/bash

# 替换成你的目标程序的进程名(比如nginx、python3等)
TARGET_PROCESS="your_target_program_name"
# 最大等待时长,防止无限等待
MAX_WAIT=60
elapsed_time=0

echo "Waiting for $TARGET_PROCESS to start..."
# 循环检查进程是否存在
while ! pgrep -x "$TARGET_PROCESS" > /dev/null; do
    sleep 1
    elapsed_time=$((elapsed_time + 1))
    if [ $elapsed_time -ge $MAX_WAIT ]; then
        echo "Timeout: $TARGET_PROCESS didn't start within $MAX_WAIT seconds."
        exit 1
    fi
done

echo "$TARGET_PROCESS is running, starting task..."

# 以下是你的原有脚本内容
stop_target_program
mount_raspberry_pi
start_target_program

然后对应的task.service可以去掉延迟,保持如下配置即可:

[Unit]
Description=Run task.sh after target program starts
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/path/to/your/task.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

这样脚本只会在系统启动时执行一次,不会因为后续程序重启而再次触发,完美解决你担心的循环问题。

方式B:利用systemd服务依赖(最推荐)

如果你的目标程序本身是用systemd服务管理的(比如有target_program.service文件),那这是最可靠的方式——直接让你的脚本服务依赖目标程序服务,systemd会自动等待目标程序完全启动后再执行你的脚本。

修改task.service的[Unit]部分:

[Unit]
Description=Run task.sh after target program starts
After=multi-user.target target_program.service  # 明确依赖目标程序服务
Requires=target_program.service  # 确保目标程序服务启动成功才执行本服务

[Service]
Type=oneshot
ExecStart=/path/to/your/task.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

这种方式完全不需要手动设置延迟或者轮询,由systemd帮你管理启动顺序,是Linux系统启动管理的标准做法,稳定性拉满。

总结

  • 临时测试用固定延迟的方式最快捷;
  • 长期使用优先选择systemd服务依赖的方式,这是最稳定的方案;
  • 如果目标程序没有对应的systemd服务,就用脚本内轮询进程的方式,配合oneshot服务也能完美避免循环触发的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:39:08