Как получить код выхода при использовании метода связи подпроцесса Python?

186

Как получить код выхода при использовании subprocessмодуля и communicate()метода Python ?

Соответствующий код:

import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]

Должен ли я делать это по-другому?

CarpeNoctem
источник

Ответы:

266

Popen.communicateустановит returncodeатрибут, когда это будет сделано (*). Вот соответствующий раздел документации:

Popen.returncode 
  The child return code, set by poll() and wait() (and indirectly by communicate()). 
  A None value indicates that the process hasnt terminated yet.

  A negative value -N indicates that the child was terminated by signal N (Unix only).

Так что вы можете просто сделать (я не проверял, но это должно работать):

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

(*) Это происходит из-за способа его реализации: после настройки потоков для чтения дочерних потоков он просто вызывает wait.

Эли Бендерский
источник
34
Этот пример помог мне, но было бы неплохо, если бы примеры не выполняли шаблон «import subprocess as sp» для импорта чего-то стандартного в качестве неясной аббревиатуры. Хотя это урезает 8 символов из кода, который следует за ним, это также затрудняет понимание и повторное использование.
уродливый
16
@uglycoyote Нет правила, согласно которому вам нужно копировать и вставлять. Просто перепечатайте его так, как вы хотите, это как 4 строки.
Джейсон С
5
@uglycoyote, вы также можете отредактировать его так, чтобы оно было чем-то вроде, from subprocess import Popenа затем просто использовать Popenвместо того, subprocess(or sp).Popenчто я бы сказал, что, вероятно, увеличивает читабельность и укорачивает строки
Mitch
2
Да ... должен позвонить, process.communicate()а затем присвоить returncodeкакую-то переменную. Если назначение сделано до вызова communicate, есть None.
WesternGun
1
Можно ли показать код возврата без перенаправления канала? Я вызываю код bash, и я хотел бы видеть вывод в реальном времени в терминале
Nisba
10

Сначала вы должны убедиться, что процесс завершен и код возврата считан с использованием .waitметода. Это вернет код. Если вы хотите получить к нему доступ позже, он сохраняется как .returncodeв Popenобъекте.

Нуфал Ибрагим
источник
24
.communicate()уже ожидает завершения подпроцесса.
Механическая улитка
8

.poll() обновит код возврата.

Пытаться

child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()

Кроме того, после .poll()вызова код возврата доступен в объекте как child.returncode.

Мэтью Вернон
источник
когда я сделал это .poll () был пуст. Мне пришлось запустить child.communicate () в строке выше child.poll (), чтобы это работало.
конец
1
Я думаю, что вы хотели использовать .wait () вместо .poll () согласно документации: docs.python.org/3/library/subprocess.html . Обратите внимание, что .wait () принимает необязательный параметр времени ожидания, который может быть удобным.
gg99
7

exitcode = data.wait(), Дочерний процесс будет заблокирован, если он записывает в стандартный вывод / ошибку и / или читает из стандартного ввода, и нет никаких одноранговых узлов.

Хачик
источник
1

Это сработало для меня. Он также печатает выходные данные, возвращаемые дочерним процессом

child = subprocess.Popen(serial_script_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    retValRunJobsSerialScript = 0
    for line in child.stdout.readlines():
        child.wait()
        print line           
    retValRunJobsSerialScript= child.returncode
Чинни Махеш
источник