![如何让脚本作为 systemd 服务运行?](https://linux22.com/image/118821/%E5%A6%82%E4%BD%95%E8%AE%A9%E8%84%9A%E6%9C%AC%E4%BD%9C%E4%B8%BA%20systemd%20%E6%9C%8D%E5%8A%A1%E8%BF%90%E8%A1%8C%EF%BC%9F.png)
我有一个 Python 脚本,其中包含一个我想每 X 分钟执行一次的函数。
from threading import Timer
x = 5
def control():
Timer(x*60, control).start()
rest_of_the_function()
control()
当我从终端在 Python 虚拟环境中运行脚本时,没有问题;当我将其作为 systemd 服务运行时,它control()
仅调用一次函数,然后不执行任何其他操作。
systemctl status myservice
如果我通过其检查服务积极的现场说活动(运行)。日志中没有错误。
/lib/systemd/system/myservice.service 文件的内容如下。
[Unit]
Description=Short description
[Service]
Type=simple
WorkingDirectory=/home/user/myservice
ExecStart=/home/user/myservice/myvenv/bin/python main.py
[Install]
WantedBy=multi-user.target
为什么只调用control()
一次?我可以修复它吗?
答案1
我认为您可能遇到了一个简单的缓冲问题。如果您正在 stdout 上查找消息(默认情况下是 systemd 单元的日志),那么您可能需要等待很长时间才能打印足够的数据,然后才能将其刷新。
对此的一个简单测试是将-u
选项添加到 python 以使输出不缓冲。请记住systemctl daemon-reload
在编辑服务单元文件后执行此操作。
您还可以使用strace
附加到正在运行的 python 进程。您可能会发现它正在等待用户 futex,但在适当的时间之后,您应该看到 futex 调用返回,然后再次输入。
答案2
当使用print()
或任何其他写入文件描述符(文件、管道等)时,flush()
如果您需要立即输出,则需要刷新缓冲区。
或者用于标准输入,标准输出和标准错误您可以使用无缓冲模式,使用-u
python 中描述的选项手册页。