Невозможно получить код завершения при запуске подпроцессов в Python с использованием Popen и start / wait - PullRequest
0 голосов
/ 13 мая 2018

Я пытаюсь создать скрипт Python, который запускает новое окно и ждет его завершения, а затем получает код выхода.Поэтому я использую Popen с start /wait, чтобы создать для него отдельное окно, но это неправильно пересылает код выхода.

Этот код суммирует проблему:

import subprocess

params = {}
params['stdout'] = subprocess.PIPE
params['stderr'] = subprocess.PIPE
params['shell'] = True

proc = subprocess.Popen('start /wait cmd /c exit 1', **params)

# This works but the above line does not
#proc = subprocess.Popen('exit 1', **params)

resultCode = proc.wait()

print(resultCode)

Документацияstart /wait предполагает, что он должен вернуть код завершения, и когда я запускаю его вручную, а затем проверяю %ERRORLEVEL%, он выглядит правильным, поэтому я не уверен, что делаю неправильно

Ответы [ 2 ]

0 голосов
/ 13 мая 2018
Команда

CMD start всегда успешно выполняется, если она успешно выполняет данную команду с помощью CreateProcess или ShellExecuteEx.Он завершается успешно, даже если ему дано указание /wait, и в итоге устанавливается %errorlevel% в ненулевое значение.Вы можете увидеть это, запустив (start /wait exit 1) && echo success.Оператор && выполняет правое выражение только в том случае, если левое выражение выполнено успешно.

Чтобы обойти эту проблему, вы можете вручную выйти из начальной оболочки, используя значение !errorlevel!, которое устанавливается start.Например:

command = 'exit 1'
shell_path = os.environ.get('ComSpec', 'cmd.exe')
start_command = 'start "" /wait {}'.format(command)
cmdline = '"{shell}" /v:on /c "({command}) & exit !errorlevel!"'.format(
          shell=shell_path, command=start_command)

proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess=PIPE)

Обратите внимание, что в приведенном выше вызове Popen не используется аргумент shell=True, поскольку оболочку необходимо запускать вручную с параметром /v:on.Это дает возможность отложенного расширения переменных окружения, используя "!"вместо "%".

Тем не менее, вам не нужна оболочка для вашей заявленной цели.Просто попросите дочерний процесс создать новую консоль, передав флаг создания CREATE_NEW_CONSOLE следующим образом:

proc = subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_CONSOLE,
           stdout=subprocess.PIPE, stderr=subprocess.PIPE)
0 голосов
/ 13 мая 2018

Использование

proc = subprocess.Popen('call cmd /c exit 1', **params)

Вместо вашего start /wait возвращает код ошибки 1 в resultCode.

По логике этого вопроса и ответа: Команда CALL vs. НАЧАТЬ с параметром / WAIT

Я полагаю, что разница в том, что start /wait не имеет общих переменных с той же средой, а call делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...