当我使用systemctl启动python应用程序时,当运行标准的shell命令(例如tail,awk等)时,python子进程失败。
代码示例:
import subprocess
process = subprocess.Popen(['awk'], stdout=subprocess.PIPE)
保存以上内容并通过python app.py运行它-没问题。
使用systemctl运行相同的命令,您将得到以下错误:
FileNotFoundError: [Errno 2] No such file or directory: 'awk': 'awk'
对于我已经安装的事实所知的所有其他命令,例如tail,sed等,也是如此。
我尝试了不同的方式来启动子过程,例如subprocess.run()
,subprocess.call()
。我还尝试使用shell=True
甚至是executable='/bin/bash
参数。
对于systemctl方面,我尝试使用systemctl start service_name --user
和配置的各种组合在本地运行-例如更改进程类型,以root身份运行,不同的用户和组。
以下是配置示例:
[Unit]
Description={{ project_name }} Service
After=network.target
[Service]
User={{ user }}
Group={{ user_group }}
Restart=always
RestartSec=1s
WorkingDirectory=/home/{{ user }}/{{ project_folder }}
ExecStart=/home/{{ user }}/{{ project_folder }}/virtualenv/bin/python start.py
[Install]
WantedBy=multi-user.target
答案 0 :(得分:0)
事实证明,python子进程正在使用PATH环境变量作为可执行文件的位置。
运行systemctl时,不提供这些内容。
我通过比较与systemctl和python app.py一起运行时的print(os.environ)发现了这一点。
在systemctl配置文件的[Service]部分中添加以下行:
Environment="PATH=/home/{{ user }}/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
答案 1 :(得分:0)
[Unit]
Description={{ project_name }} Service
After=network.target
[Service]
User={{ user }}
Group={{ user_group }}
Restart=always
RestartSec=1s
Environment="PATH=/usr/bin"
WorkingDirectory=/home/{{ user }}/{{ project_folder }}
ExecStart=/home/{{ user }}/{{ project_folder }}/virtualenv/bin/python start.py
[Install]
WantedBy=multi-user.target
这指定了程序执行 awk 命令的环境目录。
在ubuntu 20.04 LTS中,修改代码如下:
import subprocess
process = subprocess.Popen(['/usr/bin/awk'], stdout=subprocess.PIPE)