Проверка, выполняется ли подпроцесс

#python

#python

Вопрос:

Я пытаюсь использовать subprocess.popen для выполнения другого скрипта Python, который создает прослушивающий сокет. Я хочу передать ему номер по умолчанию для порта для привязки. Я также хочу отследить, используется ли порт уже и не выполняется ли привязка. Если это не удается, я хочу снова вызвать subprocess.popen и передать ему другой номер для попытки привязки.

first.py

 import subprocess

p = subprocess.Popen(["python3.7", "test.py", "4444"], shell=False)

#If p is success (bind succeeded) then I want to continue processing code. 
#Else I want to increment the port and try again.
  

start.py

 import socket, sys

HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = int(sys.argv[1])        # Port to listen on (non-privileged ports are > 1023)

def stuff():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.bind((HOST, PORT))
        except:
            print("failed to bind")
            return 1
        s.listen()
        print("Listening")
        conn, addr = s.accept()

        with conn:
            print('Connected by', addr)
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                conn.sendall(data)

stuff()
  

Комментарии:

1. Я предлагаю вам использовать эту логику внутри скрипта 🙂

2. Я бы так и сделал, но тогда мне нужно сообщить основному скрипту, к какому серверу он в конечном итоге привязан.

Ответ №1:

Пара вещей:

  • Простой возврат 1 из вызванной функции не приведет к созданию кода завершения вашего процесса 1 . Либо сделайте sys.exit(stuff()) , либо просто вызовите sys.exit(1) stuff() .

  • Вы можете дождаться успешного выполнения подпроцесса с помощью p.wait() , после чего вы можете посмотреть на p.returncode .

В вашем случае вы, вероятно, захотите сделать что-то вроде

 import subprocess

p = subprocess.Popen(["python3.7", "test.py", "4444"], shell=False)
try:
    p.wait(2)
except subprocess.TimeoutExpired:
    pass  # it was probably successful and is now listening
else:
    if p.returncode == 1:
        pass  # nope
  

И, конечно, вы могли бы сделать это с помощью просто потоков вместо подпроцессов.

Комментарии:

1. Я хочу, чтобы подпроцесс выполнялся сам по себе. Если я использовал поток и закрыл свое окно, то поток завершается. С помощью подпроцесса он выполняется до тех пор, пока я его не убью.

2. Оки. Тогда вам действительно нужен (отдельный) подпроцесс. 🙂