运行 Python 通过 systemd 的脚本无法加载模块

Running Python script via systemd fails to load module

我有一个使用 zmq 的 Python 脚本,我已经通过 pip install zmq 安装了这个库,如果通过命令行。但是,一旦我尝试让 systemd 单元调用脚本,运行ning systemctl status myservice.service 就会显示 ImportError: No module named zmq.

我的服务文件如下所示:

[Unit]
Description=Does Something

[Service]
Type=simple
ExecStart=/bin/sh /var/lib/project/runpythonscript.sh
Restart=always

[Install]
Alias=myservice.service

其中 runpythonscript.sh 是一个非常简单的 shell 脚本,运行 是我的 python 根脚本。 运行 这个 shell 脚本从命令行手动 运行 我的 python 程序完全没问题,但是调用服务会导致它找不到 zmq 模块.

感谢任何帮助。

最可能的解释是您设置了一些环境变量(例如,您的 PYTHONPATH 的扩展?)当脚本被 systemd 运行 时没有设置。

您可以尝试使用 Environment 参数(参见 [0]),因此将 PYTHONPATH(以及可能影响它的任何其他内容)设置为控制台会话中的任何内容。

[0] http://0pointer.de/public/systemd-man/systemd.exec.html#Environment=

systemd 以 root 身份运行。通过 pip 安装的模块是为用户而不是系统安装的,因此在没有 root 权限的情况下安装模块会使 root 无法访问这些模块。

为了解决这个问题,我 运行 sudo -H pip install zmqsudo -H pip3 install zmq 为 root 安装 Python 2.7 和 Python 3+ 的软件包。这允许 systemd 在尝试执行 Python 脚本时访问模块。

在我的例子中,我将 "EnvironmentFile=" 设置为用户 .bash_profile。问题是在 .bash_profile 我有类似的东西:

export PYTHONPATH=....
export PATH=....

这不适用于 systemd,我不得不将其更改为:

PYTHONPATH=....
PATH=....
export PYTHONPATH PATH

将此 属性 添加到 [Service] 部分以确保 systemd 运行 作为指定用户。

User=pi

参考AndyD的解决方法。

我遇到了类似行为的问题,但原因不完全相同。无论如何我都会在这里回复以防其他人遇到它。

我的问题是我尝试直接启动脚本(错误)

ExecStart=/var/lib/project/runpythonscript.sh

而不是通过 /bin/sh(好)

ExecStart=/bin/sh /var/lib/project/runpythonscript.sh

我原来的方法实际上适用于许多其他只做各种事情的脚本。但是当 shell 脚本文件 运行 Python 它失败了。