Python Popen在作为systemd服务运行的Python脚本中无法识别Scrapy

4

我有一个名为main.py的Python脚本,需要启动Scrapy可执行文件,因此我使用Popen来执行它(使用subprocess.call()也会得到相同的结果)。为了简化事情,我只运行了Scrapy的帮助参数。

import subprocess
...
p = subprocess.Popen(['scrapy', '-h'])

脚本需要在安装了Scrapy的virtualenv中运行。当我激活虚拟环境并执行脚本 python main.py 时,命令scrapy -h可以正常执行。
现在,我需要将该脚本作为systemd服务运行。我已经创建了该脚本的systemd unit,如下所示:
[Unit]
Description=Scrapy test
After=network.target

[Service]
User={{ scrapy_user }}
WorkingDirectory={{ test_path }}
ExecStart={{ virtualenv_path }}/bin/python {{ test_path }}/main.py

[Install]
WantedBy=multi-user.target

当我使用命令sudo systemctl start scrapy-test启用并启动服务时,代码运行正常,直到执行p = subprocess.Popen(['scrapy', '-h'])时,会抛出异常。
File "{{ test_path }}/main.py", line 52, in launch_spider
   p = subprocess.Popen(['scrapy', '-h'])
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
   errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
   raise child_exception
OSError: [Errno 2] No such file or directory

我也尝试过在Popen之前添加os.chdir('{{ virtualenv_path }}/bin')来更改工作目录,但是我得到了完全相同的异常。我确定脚本是通过virtualenv运行的,因为(1)在ExecStart属性中设置了这样,且(2)当导入系统Python中未安装的模块时,该脚本会更早地引发异常。

我有同样的问题,但在我的情况下,您的解决方案不起作用,因为它是一个第三方库(pygatt),它调用hcitool或gatttool。 - Arturo Ribes
您能否将您的答案从问题的编辑移动到一个适当的、被接受的回答中呢? - Gallaecio
3个回答

1

0

线索就在这里:

ExecStart={{ virtualenv_path }}/bin/python {{ test_path }}/main.py

scrapy 命令位于 $VIRTUAL_ENV/bin,而该路径不在 systemd$PATH 中。

您可以尝试以下操作:

import os
import subprocess
p = subprocess.Popen(['%s/bin/scrapy' % os.environ['VIRTUAL_ENV'], '-h'])

0

你可能会在后面遇到另一个问题,你可能想让Python等待子进程运行结束,可以使用p.wait()

import os
import subprocess
p = subprocess.Popen(['%s/bin/scrapy' % os.environ['VIRTUAL_ENV'], '-h'])
p.wait()

否则,systemctl 可能会过早地终止您的进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接