最稳妥的方式是用 systemd 创建服务单元文件。它适用于 Ubuntu 16.04+、CentOS 7+、Debian 8+ 等主流发行版,可精确控制启动顺序、用户身份、依赖关系和日志查看,将脚本作为正式服务管理,而非简单执行。

最稳妥的方式是用 systemd 创建服务单元文件,尤其适用于 Ubuntu 16.04+、CentOS 7+、Debian 8+ 等主流发行版。它能控制启动顺序、用户身份、依赖关系和日志查看,不是简单“跑一下脚本”,而是把脚本当作正式服务来管理。
用 systemd 创建 .service 文件(推荐)
这是当前最标准、最可控的方法:
- 把脚本放到固定位置并确保可执行:比如 sudo chmod +x /usr/local/bin/myscript.sh
- 新建服务文件:sudo vim /etc/systemd/system/myscript.service
- 填入内容(关键项已说明):
[Unit] Description=My Startup Script After=network-online.target # 确保网络就绪再运行(需要 DNS 就加这行) Wants=network-online.target # 配套启用等待网络的服务 <p>[Service] Type=oneshot User=root # 指定运行用户,非必须但建议明确 WorkingDirectory=/root # 设置工作目录,避免路径问题 ExecStart=/usr/local/bin/myscript.sh StandardOutput=journal+console StandardError=journal+console</p><p>[Install] WantedBy=multi-user.target
- 启用服务:sudo systemctl daemon-reload && sudo systemctl enable myscript.service && sudo systemctl start myscript.service
- 查日志验证:journalctl -u myscript.service -f,比写文件更可靠
通过 /etc/rc.local 启动(兼容旧习惯,需手动激活)
这个方法看起来简单,但在 systemd 系统中默认不生效,必须显式启用:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 编辑文件:sudo vim /etc/rc.local
- 确认首行为 #!/bin/bash,并在 exit 0 前添加调用命令,例如:
/usr/local/bin/myscript.sh > /var/log/rclocal.log 2>&1 - 设为可执行:sudo chmod +x /etc/rc.local
- 启用 rc-local 服务:sudo systemctl enable rc-local && sudo systemctl start rc-local
- 检查状态:sudo systemctl status rc-local,失败时看日志定位问题
注意环境与健壮性(容易忽略的关键点)
很多脚本开机不运行,不是配置错,而是没适配启动环境:
- 所有命令用绝对路径:比如写 /usr/bin/python3 而不是 python3,因为启动时 $PATH 很短
- 显式指定工作目录:脚本里用相对路径(如 ./config.json)会失败,systemd 中用 WorkingDirectory= 或脚本内加 cd /xxx
- 加基础错误处理:开头加 set -e,关键步骤后加 || exit 1,避免静默失败
- 别依赖交互式环境变量:/etc/profile 或用户 .bashrc 不会被加载,需要的变量在 service 文件里用 Environment= 显式声明
其他方式简要说明
以下方法不推荐用于新部署:
- /etc/init.d/ + chkconfig:仅适用于 SysVinit 旧系统(如 CentOS 6),在 systemd 下兼容性差,且需额外写启停逻辑
- /etc/profile.d/:只对登录终端生效,根本不会在开机时运行,不是开机自启机制
- crontab @reboot:虽能触发,但无依赖控制、无日志集成、权限和环境不稳定,适合临时任务,不适合关键脚本

















