开机自启动脚本报“找不到文件”八成是路径非绝对路径所致,因systemd无默认工作目录、不展开~、不继承shell环境,execstart等所有路径必须为绝对路径;需查systemctl status和journalctl日志定位具体失败项,核对.service文件中路径全为绝对路径,并验证脚本权限、解释器存在性及服务已正确启用。

开机自启动脚本报“找不到文件”,八成不是文件真丢了,而是路径写成了相对形式——systemd 启动时没有当前目录、不展开 ~、不继承 shell 环境,所有 ExecStart、ExecStop、脚本内部调用的命令,只要涉及文件定位,就必须是绝对路径。
看日志,锁定具体哪一行失败
先查真实错误点,别猜:
- 运行
systemctl status your-service.service,重点看最后一行 Failed 提示,比如:Failed at step EXEC spawning /home/user/./start.sh: No such file or directory→ 明确指出是./start.sh这个相对路径出问题 - 翻完整日志:
journalctl -u your-service.service -n 50 -o cat
找关键词:No such file or directory、Permission denied、command not found - 常见线索举例:
→spawning python: No such file or directory:说明没写/usr/bin/python3,只写了python
→spawning ./run.sh或spawning ~/script.sh:直接暴露相对路径或波浪号
检查 service 文件里的 ExecStart 是否全用绝对路径
打开你的 .service 文件(如 /etc/systemd/system/myapp.service),逐项核对:
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
-
ExecStart必须是完整路径,例如:ExecStart=/usr/bin/python3 /home/user/project/app.py(✅)
不能是:ExecStart=python3 app.py(❌)、ExecStart=./start.sh(❌)、ExecStart=~/myscript.sh(❌) -
WorkingDirectory只影响进程工作目录,不影响 ExecStart 查找可执行文件本身,所以它设了也不能替代绝对路径 - 如果调用的是 shell 脚本,也要确保脚本里所有命令用绝对路径:
比如写/bin/bash /opt/myscript.sh,而不是只写myscript.sh;
脚本内调用curl就得写/usr/bin/curl,调用date就得写/bin/date
验证脚本自身是否能脱离 shell 独立运行
模拟 systemd 的极简环境手动测试,最准:
- 切换到 root 用户并清空环境:
sudo su -s /bin/bash -c 'env -i PATH=/usr/bin:/bin /bin/bash -c "cd / && /usr/bin/python3 /home/user/script.py"' - 或者用 systemd-run 模拟启动:
systemd-run --scope --uid=1000 --gid=1000 --working-directory=/home/user /home/user/start.sh
这会复现相同的路径解析逻辑,失败信息和开机时一致 - 测试前确认:
脚本有可执行权限(chmod +x)
解释器路径真实存在(用which python3确认)
脚本里所有外部命令都用绝对路径(可用grep -E '^\s*(sh|bash|python|curl|jq)' /path/to/script.sh快速筛查)
确认服务是否被正确加载和启用
路径写对了,但服务没进 systemd,照样白搭:
- 检查文件位置和后缀:
ls /etc/systemd/system/*.service | grep myapp
必须是.service结尾,且在/etc/systemd/system/下(不能在子目录里) - 重载配置并启用:
sudo systemctl daemon-reload && sudo systemctl enable myapp.service - 确认已加载成功:
systemctl list-unit-files | grep myapp→ 应显示enabledsystemctl cat myapp.service→ 可查看实际加载的内容,确认没缓存旧版本










