简体   繁体   English

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

[英]Popen fails to start a process when I call it from a python script that runs as a Linux service

I have a script which on certain conditions calls Popen to create new process. 我有一个脚本,在某些情况下会调用Popen来创建新进程。 If I run this script from the command line, then Popen creates a process. 如果我从命令行运行此脚本,则Popen将创建一个进程。 But if I run the same script as a linux systemd service, then script executes normally except Popen part which fails to start a process. 但是,如果我运行与linux systemd服务相同的脚本,则该脚本将正常执行,但Popen部分无法启动进程。 Same Popen failure thing happens if I start this script from within Java application deployed and running in Tomcat 如果我从在Tomcat中部署和运行的Java应用程序中启动此脚本,也会发生相同的Popen失败事件

I've tried to mix arguments in Popen construct, but I feel that I am missing something about the whole idea behind linux processes relationships Here is the code which executes perfectly if started from cmd terminal like this: "python3 myscript.py" and fails if run as systemd service( systemctl start myscript.service - config file ofcourse exists) Fails Popen part 我尝试在Popen构造中混合参数,但是我觉得我在linux进程关系背后的整个想法上缺少一些东西。如果从这样的cmd终端启动,则代码可以完美执行:“ python3 myscript.py”并失败如果作为systemd服务运行(systemctl启动myscript.service-课程的配置文件存在)Popen部分失败

Service config file: 服务配置文件:

[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 script my_service.py itself: 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))

there are no error or warning, just video_receiver.py process never starts :-\\ 没有错误或警告,只是video_receiver.py进程永远不会启动:-\\

The issue is that the CWD for the process is different. 问题在于该过程的CWD不同。 To debug this have your program log the result of os.getcwd() . 要调试它,请让您的程序记录os.getcwd()的结果。 Another common issue although not the one occurring here is that PATH is different. 尽管不是此处出现的另一个常见问题是PATH是不同的。

lastProcess = Popen("python3 video_receiver.py")

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

One solution is to provide the full paths to python and your script in the Popen call. 一种解决方案是在Popen调用中提供python和脚本的完整路径。 The path to Python is only needed if you have Python installed in a virtual environment. 仅当您在虚拟环境中安装了Python时,才需要使用Python路径。

Another is to use os.chdir() or set the working directory in the service configuration. 另一种方法是使用os.chdir()或在服务配置中设置工作目录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 shell 脚本执行(服务 ssh 开始)有效,但是当我从 python 调用脚本时,它不起作用 - executing (service ssh start) from shell script works, but when I call the script from python, it doesnt work Python popen脚本搜索在Linux进程中运行的命令 - Python popen script to search for the command running in the process in linux 从init.d脚本执行时,Python Popen进程不起作用 - Python Popen process not working when it is executed from init.d script 从 Linux 上的 Python 脚本访问 Popen web 服务器 - Accessing Popen web server from Python script on Linux 在 CMD Works 中运行脚本但在 C# python 脚本中使用 Process.Start() 运行时失败 - Running Script in CMD Works but when ran using Process.Start() in C# python script fails Systemd服务不会将python脚本写入文件,python脚本在从cli执行时名义上运行 - Systemd service does not write python script to file, python script runs nominally when executed from cli 从Linux在python脚本中运行函数将运行整个脚本 - Running function in python script from linux runs whole script Windows服务(使用C#)可以调用无限运行的Python脚本吗? - Windows Service (in C#) that can call a Python script that runs infinitely? 在Python中将模拟与subprocess.popen结合使用以断言该进程正在运行 - Using mock with subprocess.popen in Python to assert that the process runs python脚本运行时,注销和打印的[Process Completed]是什么? - What is logout and [Process Completed] that is printed when a python script runs?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM