Завершение работающего скрипта с подпроцессом - PullRequest
0 голосов
/ 13 июля 2020

Я использую subprocess для выполнения сценария python. Я могу успешно запустить скрипт.

import subprocess
import time

proc = subprocess.Popen(['python', 'test.py', ''], shell=True)
proc.communicate()
time.sleep(10)
proc.terminate()

test.py

import time
while True:
    print("I am inside test.py")
    time.sleep(1)
    

Я вижу сообщение I am inside test.py, выводимое каждую секунду. Однако я не могу прервать скрипт, пока он все еще выполняется proc.terminate().

Может ли кто-нибудь помочь мне?

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Прежде всего, не используйте список для передачи аргументов для subprocess.Popen(), если вы используете shell = True !, измените команду на string, "python test.py".

Popen.communicate(input=None, timeout=None) - это метод класса блокировки, он должен взаимодействовать с процессом и ждать завершения процесса и устанавливать атрибут кода возврата.

, поскольку ваш test.py работает бесконечно, пока l oop, он никогда не вернется!

у вас есть 2 варианта тайм-аута процесса proc, который вы создали:

  1. назначьте аргумент ключевого слова тайм-аута в, например, времени процесс в течение 5 секунд, communicate(timeout=5) метод. Если процесс proc не завершится через timeout секунд, будет вызвано TimeoutExpired exception. Перехват этого исключения и повторная попытка связи не приведет к потере вывода (в вашем случае дочерние выводы вам не нужны, но я упомяну об этом в примере ниже). ВНИМАНИЕ Дочерний процесс не уничтожается, если timeout expires, поэтому для правильной очистки приложение с хорошим поведением должно убить дочерний процесс (proc) и завершить sh обмен данными.
  2. с помощью метода poll и синхронизация с помощью метода вызова.

связь с тайм-аутом

try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

опрос с time.sleep

proc = subprocess.Popen('python test.py', shell=True)
t=10
while proc.poll() is None and t >= 0:
    print('Still sleeping')
    time.sleep(1)
    t -= 1
proc.kill()
1 голос
/ 13 июля 2020

proc.communicate ожидает завершения процесса sh, если вы не укажете тайм-аут. Ваш процесс не завершается, и у вас нет тайм-аута, поэтому communicate никогда не возвращается. Вы можете проверить это с помощью print после звонка. Вместо этого добавьте тайм-аут и перехватите его исключение

import subprocess
import time

proc = subprocess.Popen(['python', 'test.py', ''], shell=True)
try:
    proc.communicate(timeout=10)
except subprocess.TimeoutExpired:
    proc.terminate()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...