Python 守护进程和 systemd 服务 [英] Python daemon and systemd service
问题描述
我有一个简单的 Python 脚本作为守护进程.我正在尝试创建 systemd 脚本以便能够在启动期间启动此脚本.
I have a simple Python script working as a daemon. I am trying to create systemd script to be able to start this script during startup.
当前的 systemd 脚本:
Current systemd script:
[Unit]
Description=Text
After=syslog.target
[Service]
Type=forking
User=node
Group=node
WorkingDirectory=/home/node/Node/
PIDFile=/var/run/zebra.pid
ExecStart=/home/node/Node/node.py
[Install]
WantedBy=multi-user.target
node.py:
if __name__ == '__main__':
with daemon.DaemonContext():
check = Node()
check.run()
run
包含 while True
循环.
我尝试使用 systemctl start zebra-node.service
运行此服务.不幸的是,服务从未完成说明序列 - 我必须按 Ctrl+C.脚本正在运行,但状态正在激活,一段时间后它更改为停用.现在我正在使用 python-daemon(但在我尝试不使用它之前,症状是相似的).
I try to run this service with systemctl start zebra-node.service
. Unfortunately service never finished stating sequence - I have to press Ctrl+C.
Script is running, but status is activating and after a while it change to deactivating.
Now I am using python-daemon (but before I tried without it and the symptoms were similar).
我应该为我的脚本实现一些额外的功能还是 systemd 文件不正确?
Should I implement some additional features to my script or is systemd file incorrect?
推荐答案
它没有完成启动顺序的原因是,对于 Type forking
你的启动过程预计会 fork 并退出 (请参阅 $ man systemd.service - 搜索分叉).
The reason, it does not complete the startup sequence is, that for Type forking
your startup process is expected to fork and exit (see $ man systemd.service - search for forking).
一种选择是少做.使用 systemd,通常不需要创建守护进程,您可以直接运行代码,无需守护进程.
One option is to do less. With systemd, there is often no need to create daemons and you may directly run the code without daemonizing.
#!/usr/bin/python -u
from somewhere import Node
check = Node()
check.run()
这允许使用称为 simple
的更简单的服务类型,因此您的单元文件将如下所示.
This allows using simpler Type of service called simple
, so your unit file would look like.
[Unit]
Description=Simplified simple zebra service
After=syslog.target
[Service]
Type=simple
User=node
Group=node
WorkingDirectory=/home/node/Node/
ExecStart=/home/node/Node/node.py
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
请注意,python shebang 中的 -u
不是必需的,但是如果您将某些内容打印到 stdout 或 stderr,-u
可以确保,有没有输出缓冲,打印的行将立即被 systemd 捕获并记录在日志中.没有它,它会出现一些延迟.
Note, that the -u
in python shebang is not necessary, but in case you print something out to the stdout or stderr, the -u
makes sure, there is no output buffering in place and printed lines will be immediately caught by systemd and recorded in journal. Without it, it would appear with some delay.
为此,我将 StandardOutput=syslog
和 StandardError=syslog
行添加到单元文件中.如果您不关心日记中的打印输出,请不要关心这些行(它们不必存在).
For this purpose I added into unit file the lines StandardOutput=syslog
and StandardError=syslog
. If you do not care about printed output in your journal, do not care about these lines (they do not have to be present).
虽然您的问题的标题明确询问了守护进程,但我想问题的核心是如何让我的服务运行",而使用主进程似乎更简单(您没有根本不必关心守护进程),它可以被认为是对您问题的回答.
While the title of your question explicitly asks about daemonizing, I guess, the core of the question is "how to make my service running" and while using main process seems much simpler (you do not have to care about daemons at all), it could be considered answer to your question.
我认为,很多人使用守护进程只是因为每个人都这样做".使用 systemd,守护进程的原因通常已经过时.使用守护进程可能有一些原因,但现在这种情况很少见.
I think, that many people use daemonizing just because "everybody does it". With systemd the reasons for daemonizing are often obsolete. There might be some reasons to use daemonization, but it will be rare case now.
将 python -p
修正为正确的 python -u
.谢谢kmftzg
fixed python -p
to proper python -u
. thanks kmftzg
这篇关于Python 守护进程和 systemd 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!