gpt4 book ai didi

python - 当我从作为 Linux 服务运行的 python 脚本调用它时,Popen 无法启动进程

转载 作者:太空宇宙 更新时间:2023-11-04 11:46:11 25 4
gpt4 key购买 nike

我有一个脚本,它在特定条件下调用 Popen 来创建新进程。如果我从命令行运行此脚本,则 Popen 会创建一个进程。但是,如果我运行与 linux systemd 服务相同的脚本,那么脚本将正常执行,除了无法启动进程的 Popen 部分。如果我从在 Tomcat 中部署和运行的 Java 应用程序中启动此脚本,则会发生相同的 Popen 故障

我试图在 Popen 构造中混合参数,但我觉得我遗漏了一些关于 linux 进程关系背后的整个想法这是从 cmd 终端启动时完美执行的代码:“python3 myscript.py”,如果作为 systemd 服务运行则失败(systemctl start myscript.service - 配置文件当然存在)失败 Popen 部分

服务配置文件:

[Unit]
Description=Some Service
After=multi-user.target
Conflicts=getty@tty1.service

[Service]
Type=simple
ExecStart=/usr/bin/python3 /usr/bin/my_service.py
StandardInput=tty-force

[Install]
WantedBy=multi-user.target

Python 脚本 my_service.py 本身:

import socket, os, signal, psutil
from subprocess import Popen, PIPE, DEVNULL

def find_free_port():
s = socket.socket()
# Bind to a free port provided by the host.
s.bind(('', 0))
return s.getsockname()[1]

HOST = '91.230.195.104'
PORT = 65440

lastProcess = None
currentPID = os.getpid()

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:

s.bind((HOST, PORT))
s.listen()

while True:
try:
print('Waiting for new Connection..')

conn, addr = s.accept()

if lastProcess != None:
current_process = psutil.Process(lastProcess.pid)
children = current_process.children(recursive=True)
for child in children:
if child.pid != currentPID:
os.kill(child.pid, signal.SIGKILL)

print('\nConnected to: '+str(addr))

port_sender = find_free_port()
port_videolink = None

while True:
port_videolink = find_free_port()
if port_sender != port_videolink:
break

with conn:
data = conn.recv(1024)
print('DRONE ID: '+str(data.decode()))
if data:
conn.sendall(bytes(str(port_sender)+':'+str(port_videolink), 'utf-8'))
lastProcess = Popen("python3 video_receiver.py --port_videolink="+str(port_videolink)+
" --port_sender="+str(port_sender), shell=True, preexec_fn=os.setpgrp, stdout=PIPE, stderr=PIPE)
print("Videofeed port: "+str(port_videolink)+"\n")
except Exception as e:
print(str(e))

没有错误或警告,只是 video_receiver.py 进程永远不会启动 :-\

最佳答案

问题是进程的 CWD 不同。要对此进行调试,请让您的程序记录 os.getcwd() 的结果。另一个常见问题(虽然不是此处发生的问题)是 PATH 不同。

lastProcess = Popen("python3 video_receiver.py")

失败,因为 os.path.isfile(os.path.join(os.getcwd(), "video_receiver.py")) == False

一种解决方案是在 Popen 调用中提供 python 和脚本的完整路径。只有在虚拟环境中安装了 Python 时,才需要 Python 的路径。

另一种是使用os.chdir()或者在服务配置中设置工作目录。

关于python - 当我从作为 Linux 服务运行的 python 脚本调用它时,Popen 无法启动进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57647539/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com