最稳妥的方式是用 systemd 创建服务单元文件,适合 ubuntu 22.04、debian 12、centos stream 9 等主流系统;若系统较旧或极简(如 buildroot),可改用 /etc/rc.local。

最稳妥的方式是用 systemd 创建服务单元文件,适合 Ubuntu 22.04、Debian 12、CentOS Stream 9 等主流系统。如果系统较旧或极简(如 Buildroot),可改用 /etc/rc.local。不推荐直接改 /etc/profile 或用户级 crontab @reboot——它们启动太早或太晚,环境不可靠,日志难查。
用 systemd 设置(现代发行版首选)
这是官方标准,支持依赖控制、失败重试、日志集成,且能精准指定启动时机。
- 把脚本放到固定位置,比如
/usr/local/bin/myscript.sh,确保有执行权限:sudo chmod +x /usr/local/bin/myscript.sh - 创建服务文件:
sudo vim /etc/systemd/system/myscript.service - 填入内容(关键项已说明):
[Unit]
Description=My Startup Script
After=network.target multi-user.target # 确保网络和基础服务就绪
[Service]
Type=oneshot
ExecStart=/usr/local/bin/myscript.sh
RemainAfterExit=yes # 用于只运行一次的脚本
User=root
WorkingDirectory=/usr/local/bin
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target - 启用并验证:
sudo systemctl daemon-reloadsudo systemctl enable myscript.servicesudo systemctl start myscript.service # 立即测试sudo journalctl -u myscript.service -n 20 # 查日志
用 /etc/rc.local(兼容性强,适合新手或旧系统)
它在多数 systemd 和 SysVinit 系统中都有效,执行时机晚、环境稳定,适合简单一次性任务。
- 检查是否存在:
ls -l /etc/rc.local - 若不存在,创建并赋权:
sudo touch /etc/rc.localsudo chmod +x /etc/rc.localecho '#!/bin/bash' | sudo tee /etc/rc.local - 编辑该文件,在
exit 0前添加你的命令:sudo vim /etc/rc.local
加入类似这行(带日志更安心):/usr/local/bin/myscript.sh >> /var/log/myscript-start.log 2>&1 - 在 systemd 系统中需启用 rc-local 服务:
sudo systemctl enable rc-localsudo systemctl start rc-localsudo systemctl status rc-local # 确认 Active: active
注意事项:让脚本真正可靠
很多自启失败不是配置问题,而是脚本本身没扛住启动环境。
- 所有命令写绝对路径:用
/bin/bash不用bash,用/usr/bin/python3不用python3 - 加等待逻辑(尤其涉及网络、挂载、串口):
脚本开头加sleep 5或检查关键资源就绪:until ping -c1 google.com &>/dev/null; do sleep 2; done - 显式设置工作目录和环境变量:
cd /path/to/script || exit 1export PATH="/usr/local/bin:/usr/bin:/bin" - 务必记录日志:哪怕只是
date >> /tmp/myscript.log,重启后能第一时间定位是否执行过
不建议的方案(易踩坑)
以下方法看似简单,但实际隐患多,仅作了解:
-
@rebootin crontab:用户级 cron 启动太早,$PATH不全,且 root cron 可能被禁用;非 root 用户无法访问硬件或系统路径 - 放
/etc/profile.d/:只对交互式登录 shell 生效,开机自启时根本不会读取 - 硬链到
/etc/rc.d/rc3.d/:SysVinit 时代遗留方式,systemd 系统已不识别,强行使用可能被覆盖或忽略











