开机自启动服务没拉起来,问题大概率出在systemd加载、依赖、权限或环境四环节;按顺序查:先确认服务是否被正确识别启用,再查真实日志定位失败原因,接着验证脚本路径权限与执行环境,最后排查rc.local失效、网络依赖不足或SELinux拦截等静默陷阱。

开机自启动服务没拉起来,别急着重写脚本或怀疑系统坏了。问题大概率出在 systemd 加载、依赖、权限或环境这四个环节里。只要按顺序查,90% 的情况三分钟内就能定位。
第一步:确认服务是否被 systemd 正确识别和启用
很多故障卡在最前面——服务压根没注册进系统。
- 检查文件位置和命名:必须放在 /etc/systemd/system/ 下,且后缀严格为 .service(不是 .service.txt,也不能在子目录里)
- 验证是否已启用:
systemctl is-enabled your-service.service—— 输出必须是 enabled;若为 disabled 或 unknown,说明systemctl enable没生效 - 确认加载状态:
systemctl list-unit-files | grep your-service—— 应显示 enabled 且状态为 loaded;若没出现或显示 invalid,说明 service 文件有语法错误或路径未被 daemon-reload 刷新
第二步:检查服务启动时的真实行为和失败原因
手动 start 成功但开机不启?那是时序或环境问题;手动也失败?先看日志。
- 立即查状态:
systemctl status your-service.service—— 关注 Active: 行(是否 failed)和下方最近几行日志,常直接提示 Permission denied、No such file 或 Exec format error - 翻完整启动日志:
journalctl -u your-service.service --since "boot"—— 查看本次开机全程记录,重点找 Failed to start、exited with code 或 timed out - 对比手动 vs 开机行为:执行
sudo systemctl start your-service.service并立刻journalctl -u your-service.service -n 20,再重启看日志差异——若手动能跑而开机不能,大概率是After=依赖未满足,或User=指定的用户在开机早期不可用
第三步:排查脚本或二进制本身的问题
即使服务单元文件没问题,被调用的程序也可能卡住。
- 检查 ExecStart 路径:
systemctl show --property=ExecStart your-service.service,然后ls -l确认该文件存在、可执行,且路径中无中文或空格 - 验证脚本权限与解释器:脚本需 chmod +x,且首行 shebang(如
#!/bin/bash)必须匹配实际执行环境;Ubuntu 16.04+ 默认用/bin/sh(dash),不支持source或数组语法 - 测试脚本在最小环境运行:
sudo -u your-user /bin/bash -c "/path/to/script.sh"—— 模拟 systemd 启动时的用户上下文,观察是否报错
第四步:留意典型“静默失败”陷阱
有些失败不会报错,只是默默跳过。
-
rc.local 兼容层失效:Ubuntu 20.04+、CentOS 7+ 中
/etc/rc.local不再原生生效,需先systemctl enable rc-local,且文件必须含#!/bin/bash和exit 0在最后一行,中间不能有空行 -
网络依赖未就绪:若服务需要联网(如拉取远程配置),
After=network.target不够可靠;改用After=network-online.target并添加Wants=network-online.target -
SELinux 或 AppArmor 拦截:执行
ausearch -m avc -ts recent | grep your-service(SELinux)或dmesg | grep audit | grep your-service(AppArmor),看是否有拒绝日志


















