【问题标题】:Python Module not Found from `systemd` service Script从“systemd”服务脚本中找不到 Python 模块
【发布时间】:2020-03-19 15:03:13
【问题描述】:

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

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

import paho.mqtt.client as mqtt

如果我使用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

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

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

确认路径分配存在--

我从 python 解释器中得到:

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

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']

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

更新/澄清:

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

【问题讨论】:

  • “来自我得到的 python 解释器”。你是以 root 身份做的...?
  • 不,这是作为 pi 完成的(系统上唯一的用户);需要明确的是,sudo 也没有完成。我认为它与系统文件有关 - 它作为 pi 运行良好,但在 systemd 中启动时却没有。我并没有忘记我已经在用户 pi 下本地安装了所有东西 - 但我也以用户 pi 的身份运行所有东西。 (?)

标签: python bash systemd


【解决方案1】:

尝试用root安装模块。

【讨论】:

    【解决方案2】:

    这可能是 python 的链接问题。如果您要通过 pip 安装库,它可能会也可能不会正确链接或安装。我建议使用类似的东西重新安装 mqtt 库...

    sudo -H pip3 install --system paho-mqtt
    

    另外,我注意到您的导入错误。你写道:import pho.mqtt.client as mqtt

    应该是:

    import paho.mqtt.client as mqtt
    

    【讨论】:

      【解决方案3】:

      我想我知道问题出在哪里了...systemd 默认以root 运行其服务。我认为哪个/应该(见下文)允许与 root 使用 sudo 为另一个用户或 cli 上的实际 root 用户运行的东西等效。

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

      [Service]
      User=pi
      ExecStart=/home/pi/my_program.sh
      

      这允许服务运行而不会出现错误(上述错误)。

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

      [Service]
      User=root
      ExecStart=/home/pi/my_program.sh
      

      原因:

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

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

      欢迎解释和教育。谢谢。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-18
        • 1970-01-01
        • 1970-01-01
        • 2017-08-01
        • 2021-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多