用 systemd 托管 Python 脚本:开机自启、崩溃重启与日志查看

举报
yd_217417492 发表于 2026/10/26 09:12:18 2026/10/26
【摘要】 nohup 和 screen 只能让脚本暂时在后台跑,机器重启就没了。本文用一个 Python 监控脚本为例,给出 systemd unit 的完整写法,并说明日志、环境变量、虚拟环境和常见排错顺序。

nohup 和 screen 的问题

临时跑一个 Python 脚本,用 nohup python3 job.py & 或 screen 就够了。但这类方式有几个明显短板:机器重启后不会自动拉起,脚本崩了没人管,标准输出散落在 nohup.out 里,时间一长很难查。把它交给 systemd,开机自启、崩溃重启、日志收集三件事一次解决。

一个最小可用的 unit

假设脚本在 /opt/prize-watch/monitor.py,用虚拟环境 /opt/prize-watch/.venv,运行用户是 ubuntu。新建 /etc/systemd/system/monitor.service:

[Unit]
Description=Prize watch monitor
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/prize-watch
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/prize-watch/.venv/bin/python /opt/prize-watch/monitor.py --loop
Restart=on-failure
RestartSec=5
TimeoutStopSec=20

[Install]
WantedBy=multi-user.target

几个参数值得说明:Type=simple 适合前台常驻的脚本;Restart=on-failure 只在退出码非 0 或被信号杀掉时重启;RestartSec=5 避免崩溃后立刻反复拉起;PYTHONUNBUFFERED=1 让日志实时进入 journal,而不是卡在缓冲区里。

启用与查看状态

sudo systemctl daemon-reload
sudo systemctl enable --now monitor.service
systemctl status monitor.service

改过 unit 文件后必须再执行一次 daemon-reload,否则 systemd 用的还是旧配置。这一步漏掉,会出现“明明改了却没生效”的情况。

日志用 journalctl 看

journalctl -u monitor.service -n 100 --no-pager
journalctl -u monitor.service -f
journalctl -u monitor.service --since "1 hour ago"

脚本里直接 print 的内容会进入 journal,不需要自己再重定向到文件。如果日志量很大,可以在 unit 里加 StandardOutput=append:/var/log/monitor.log,或者用 journald 的 SystemMaxUse 限制总量。

三个常见坑

  1. ExecStart 用了相对路径。systemd 不经过 shell,python3 可能找不到,必须写绝对路径。
  2. 环境变量没有继承。登录 shell 里的 PATH、代理、API Key 不会自动带进来。用 Environment= 或 EnvironmentFile= 显式声明,后者权限建议 600。
  3. 虚拟环境没激活。直接调用 .venv/bin/python,不要依赖 source activate,systemd 不会执行 shell 初始化脚本。

定时任务也可以用 timer

如果脚本是“跑一次就退出”,比起常驻循环,更推荐 systemd timer:monitor.timer 里写 OnCalendar=*:0/10,对应的 service 写 Type=oneshot。它和 cron 的区别是自带日志、支持依赖关系和错过补偿(Persistent=true)。

排错顺序

  1. systemctl status 看退出码和最后一次日志;
  2. journalctl -u 看完整报错堆栈;
  3. 手动用同样的用户和绝对路径执行一次 ExecStart;
  4. 确认 unit 改完后执行过 daemon-reload。

把脚本从 nohup 迁到 systemd 只需要十几分钟,之后重启服务器、脚本崩溃都不用人盯着,日志也有统一入口,长期维护成本会低很多。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。