我正在尝试让一个用 Python 编写的项目在服务器上运行。我创建了以下服务文件:
[Unit]
Description=My bot service
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3.10 /home/path/to/bot.py
[Install]
WantedBy=multi-user.target
但这段代码不起作用。如果我检查服务状态,它会返回以下内容:
● test.service - My bot service
Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2022-10-21 08:16:07 UTC; 15s ago
Process: 156695 ExecStart=/usr/bin/python3.10 /home/path/to/bot.>
Main PID: 156695 (code=exited, status=1/FAILURE)
Oct 21 08:16:07 instance-1 systemd[1]: test.service: Scheduled restart job, restart coun>
Oct 21 08:16:07 instance-1 systemd[1]: Stopped My bot service.
Oct 21 08:16:07 instance-1 systemd[1]: names.service: Start request repeated too quickly.
Oct 21 08:16:07 instance-1 systemd[1]: test.service: Failed with result 'exit-code'.
Oct 21 08:16:07 instance-1 systemd[1]: Failed to start My bot service.
当我直接执行机器人 ( /usr/bin/python3.10 /home/path/to/bot.py
) 时,它就可以工作。
当我将一个简单的 Python 脚本作为服务运行时,它也可以工作。
我只是不明白是什么导致了项目内部的问题。在配置文件中添加WorkingDirectory
参数没有改变任何东西
答案1
bot.py
正在返回1
。
您需要检查代码以了解在哪些条件下可以使用该代码退出。
我要做的第一件事就是删除Restart=always
.您可以看到您的脚本失败,然后重新启动,然后重新启动,然后重新启动,然后停止尝试。最有可能的是,如果第一次失败,以后就不会成功。因此,在一切运行良好之前,几乎不需要这条线。它所做的只是污染你的输出并在开发过程中造成混乱。如果没有这个,systemctl status
你可能会得到最后几行stdout
。
我要做的下一件事是启动该服务并检查日志:
$ sudo systemctl start test.service
$ journalctl -u test.service --since "5 minutes ago"
这可能会为您提供有关所发生情况的 stdout 或 stderr 线索。特别检查异常痕迹。
如果日志中没有任何输出,则可能是因为python
在刷新缓冲区之前退出。使用python
的-u
选项确保输出不被缓冲:
ExecStart=/usr/bin/python3.10 -u /home/path/to/bot.py
最后,如果此机器人创建一个窗口并具有 GUI,则您需要采取特殊步骤(在总线--user
或设置DISPLAY=
环境上运行它)。如果您需要 GUI,我可以提供更多信息。这是人们遇到“我可以运行它,但 systemd 不能”问题的一个非常常见的原因。