从“systemd”服务脚本中找不到 Python 模块

Bil*_*ong 4 python bash systemd

看了几十个以前的答案,我很惊讶我找不到任何东西......

我将pahomqtt 库用于一个非常简单的 python 程序来报告一些数据(在 Raspberry Pi 上运行)。我从 python 程序 (my_program.py) 中导入的是:

import paho.mqtt.client as mqtt
Run Code Online (Sandbox Code Playgroud)

如果我使用python my_program.py它从命令行运行程序,它运行时不会出错。但是,我试图将其设置为系统服务来管理其执行。我已经用类似的 python 程序完成了十几次,设置了各种 bash 脚本和服务文件。除了这个,他们都可以工作。我提到这一点是因为我认为它与 bash 或服务本身无关。为了完整起见,这里是设置。

从运行的 bash 脚本/systemd -

## Service (my_program.service):
ExecStart=/home/pi/my_program.sh

## and bash (my_program.sh)
python /home/pi/my/directory/my_program.py
Run Code Online (Sandbox Code Playgroud)

当我去启动服务时,我得到:

pi@ArmstrongSE:/etc/systemd/system $ sudo systemctl status my_program
* my_program.service
   Loaded: loaded (/etc/systemd/system/my_program.service; static; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sat 2019-11-23 13:59:58 PST; 22s ago
  Process: 31100 ExecStart=/home/pi/my_program.sh (code=exited, status=1/FAILURE)
 Main PID: 31100 (code=exited, status=1/FAILURE)

Nov 23 13:59:54 ArmstrongSE systemd[1]: Started my_program.service.
Nov 23 13:59:54 ArmstrongSE my_program.sh[31100]: Starting MQTT Transmitter
Nov 23 13:59:55 ArmstrongSE my_program.sh[31100]: /home/pi/data/solar/20191123135605.json
Nov 23 13:59:58 ArmstrongSE my_program.sh[31100]: Traceback (most recent call last):
Nov 23 13:59:58 ArmstrongSE my_program.sh[31100]:   File "/home/pi/my/directory/my_program.py", line 25, in <module>
Nov 23 13:59:58 ArmstrongSE my_program.sh[31100]:     import paho.mqtt.client as mqtt
Nov 23 13:59:58 ArmstrongSE my_program.sh[31100]: ImportError: No module named paho.mqtt.client
Run Code Online (Sandbox Code Playgroud)

确认路径分配在那里 - -

从 python 解释器我得到:

>>> import paho.mqtt.client as mqtt
>>> print(mqtt.__file__)
/home/pi/.local/lib/python2.7/site-packages/paho/mqtt/client.pyc
Run Code Online (Sandbox Code Playgroud)

sys.path报告:

>>> import sys
>>> print(sys.path)
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-arm-linux-gnueabihf', 
'/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', 
'/home/pi/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', 
'/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/gtk-2.0']
Run Code Online (Sandbox Code Playgroud)

我被卡住了......关于为什么这不会加载的任何想法?

更新/澄清:

我可以从任何地方(任何目录)运行 bash 脚本并且它可以工作。所以,它一定是systemd设置中的东西(?)。

Bil*_*ong 5

我想我想出了问题所在...... systemd默认情况下将其服务作为root. 我认为(见下文)这将/应该允许相当于root为另一个用户或rootcli 上的实际用户使用 sudo运行的东西。

只关注 systemd 的服务文件,我在手册页中发现有一个[Service]参数可让您指定谁运行服务。在这种情况下,我尝试将参数设置为:

[Service]
User=pi
ExecStart=/home/pi/my_program.sh
Run Code Online (Sandbox Code Playgroud)

这允许服务在没有错误的情况下运行(上面提到的错误)。

我也可以使用这些设置并无错误地执行:

[Service]
User=root
ExecStart=/home/pi/my_program.sh
Run Code Online (Sandbox Code Playgroud)

为什么:

对于发现自己在这里的其他人,如果您User=从该[Service]部分中省略参数,则默认值为root. 但是,这与将User=参数设置为root(例如,User=root)或另一个用户(在我的情况下为 pi)不同。

我不太明白其中的细微差别,但是从有关环境变量的文档中,该User=参数用于设置$PATH变量。如果服务文件没有User=设置,我认为它会导致路径分配出现问题。我认为这就是为什么设置User=为 pi 或 root 可以解决这个问题,而使用默认值似乎会导致问题。

欢迎解释和教育。谢谢。