systemd是ubuntu 20.04+唯一推荐的开机自启机制;因rc.local、crontab @reboot等存在挂载延迟、环境缺失、无日志、无重启策略等问题,易静默失效;必须用含after、user、workingdirectory、environment、standardoutput/error、restart等字段的systemd服务文件,并reload、enable、start后实机重启验证。

systemd 是当前 Ubuntu(20.04 及以后)唯一推荐、稳定且可追踪的开机自启机制。其他方式如 rc.local、crontab @reboot 或桌面自动启动,要么默认禁用、要么依赖用户登录、要么无法捕获异常退出——它们不是“不能用”,而是容易在重启后静默失效。
为什么不能直接用 crontab @reboot
看似简单:@reboot /usr/bin/python3 /path/to/script.py,但实际踩坑极多:
-
@reboot触发时机过早,/home分区可能尚未挂载(尤其使用加密主目录或网络磁盘时),脚本路径直接报No such file or directory - 环境变量缺失:没有
$PATH、$HOME、$PYTHONPATH,常见报错是ImportError: No module named 'requests'或ModuleNotFoundError - 无日志输出:错误全丢进黑洞,
journalctl查不到,stdout和stderr默认不保存 - 不支持重启策略:脚本崩溃后不会自动拉起,得靠外部轮询,可靠性差
必须用 systemd 服务文件,且关键字段不能省
以 /home/ubuntu/myscript.py 为例,创建服务文件 /etc/systemd/system/myscript.service,内容必须包含以下几项才能真正可靠:
-
After=multi-user.target或更稳妥的After=network-online.target(如果脚本要联网) -
User=ubuntu:明确指定运行用户,避免以root运行带来的权限和路径问题 -
WorkingDirectory=/home/ubuntu:显式设置工作目录,否则open('log.txt', 'a')会写到/根目录下 -
Environment="PATH=/usr/local/bin:/usr/bin:/bin":补全基础路径,防止找不到python3或其他依赖命令 -
StandardOutput=journal和StandardError=journal:确保所有输出进系统日志,后续可用journalctl -u myscript.service查看 -
Restart=on-failure(非always):只在非 0 退出码时重启,避免无限崩溃循环
示例最小可行配置:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
[Unit] Description=My Python Script After=network-online.target Wants=network-online.target [Service] Type=simple User=ubuntu WorkingDirectory=/home/ubuntu Environment="PATH=/usr/local/bin:/usr/bin:/bin" ExecStart=/usr/bin/python3 /home/ubuntu/myscript.py Restart=on-failure RestartSec=5 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
Python 虚拟环境必须显式调用解释器
如果你的脚本依赖 venv 或 conda 环境,ExecStart 不能写成 /path/to/venv/bin/python script.py 就完事——它仍可能因 LD_LIBRARY_PATH 或激活脚本未执行而失败。
- 正确做法:用完整绝对路径调用虚拟环境中的
python,例如ExecStart=/home/ubuntu/myenv/bin/python /home/ubuntu/myscript.py - 若需激活环境变量(比如某些 C 扩展依赖
CONDA_DEFAULT_ENV),改用Type=exec+ExecStart=/bin/bash -c 'source /path/to/activate && python script.py'(不推荐,增加 shell 层级易出错) - 更健壮的做法:把所有依赖打包进虚拟环境,确保
python二进制本身已包含全部链接库,然后只调用它
启用后必须 reload + enable + start,缺一不可
写完 .service 文件后,常见遗漏步骤导致“明明配了却没反应”:
- 忘记
sudo systemctl daemon-reload:systemd 不会自动感知新文件,不 reload 就等于没写 - 只
start没enable:临时启动一次,重启后失效;必须sudo systemctl enable myscript.service才写入开机启动链 - 没检查状态:
sudo systemctl status myscript.service看 Active 是否为active (running),若为inactive (dead)或报failed,立刻查journalctl -u myscript.service -n 30 - 路径权限被忽略:确保
myscript.py有可读权限(chmod 644),且python能访问其所在目录(ls -ld /home/ubuntu权限至少为drwxr-xr-x)
真正跑通的关键,从来不是“怎么写 service 文件”,而是“怎么验证它在重启后依然活着”。每次修改后,务必执行 sudo reboot 实测一次——模拟真实场景,别只信 start 的即时反馈。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










