在现代主流 Linux 发行版上,使用 systemd 的 unit 文件管理脚本自启是最标准且维护成本最低的方案,适合需要随系统启动运行的后台任务。
先说结论:systemd 是当前 Linux 初始化的事实标准,比传统的 rc.local 或 init.d 脚本更可靠,能更好地处理依赖和日志。
- 适合:CentOS 7+、Ubuntu 16+、Debian 8+ 等使用 systemd 的系统
- 先准备:确保脚本本身有执行权限,且路径固定
- 验收:通过 systemctl status 和 journalctl 确认运行状态
命令速用版
# 创建服务文件
sudo systemctl edit `--force` my-script.service
# 填入配置后启用
sudo systemctl enable my-script.service
sudo systemctl start my-script.service
为什么会这样
早期 Linux 常用 /etc/rc.local 或 init.d 脚本,但它们在依赖管理和失败重试上能力有限。systemd 通过 unit 文件明确定义了服务的启动顺序、依赖关系以及失败后的行为,且统一了日志输出,排查问题更方便。
分步处理
1. 准备脚本
将你的脚本放到合适的位置,例如 /usr/local/bin/myscript.sh,并赋予执行权限:
chmod +x /usr/local/bin/myscript.sh
2. 编写 Unit 文件
在 /etc/systemd/system/ 下创建文件,例如 myscript.service。最小配置如下:
[Unit]
Description=My Custom Script
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/myscript.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
注意:如果脚本需要长期运行,去掉 RemainAfterExit 并将 Type 设为 simple 或 forking。
3. 重载并启用
修改配置后需要重载 systemd 守护进程,然后启用开机自启:
sudo systemctl daemon-reload
sudo systemctl enable myscript.service
怎么验证是否生效
使用以下命令检查服务状态是否为 active (exited) 或 active (running):
systemctl status myscript.service
查看脚本的标准输出和错误日志,确认是否有报错:
journalctl -u myscript.service -n 50
重启系统后,再次执行上述命令,确认服务是否自动拉起。
常见坑
- 环境变量缺失:systemd 启动的环境变量比交互式 shell 少,脚本中涉及的路径建议写绝对路径。
- 权限问题:确保脚本文件及其调用的资源对运行用户可读可执行,默认以 root 运行,如需普通用户请配置
User=。 - 网络依赖:如果脚本需要联网,务必在 [Unit] 段添加
After=network.target或network-online.target。 - 输出丢失:默认日志走 journal,如果脚本依赖写入特定文件,请确保有写权限。