Как получить код выхода при использовании метода связи подпроцесса Python?
Как получить код выхода при использовании Python subprocess
модуль и communicate()
метод?
Соответствующий код:
import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]
Должен ли я делать это по-другому?
8 ответов
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 hasn’t 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
,
Просто чтобы указать на распространенное заблуждение, вы должны избегать всегда, когда можете. Чтобы процитировать документацию,
Рекомендуемый подход к вызову подпроцессов заключается в использовании
run()
функция для всех вариантов использования, которые она может обрабатывать. Для более продвинутых вариантов использования базовыйинтерфейс можно использовать напрямую.
Если вы просто хотите запустить подпроцесс и дождаться его завершения, это одна строка кода с
subprocess.run
или его устаревшие братья и сестры
subprocess.call
а также
subprocess.check_output
, и вам не нужно копировать/вставлять и/или разбираться в тонкостях
communicate
а также
wait
и т. д. методы, необходимые вокруг низкоуровневого
Popen
объект.
import subprocess
proc = subprocess.run(
[openRTSP] + opts.split(),
capture_output=True,
# avoid having to explicitly encode
text=True)
data = proc.stdout
result = proc.returncode
Если вы не хотите фиксировать вывод процесса, возможно, замените
capture_output=True
с
stdout=subprocess.DEVNULL
(и, возможно, аналогично для
stderr
); в отсутствие любого из них выходные данные будут просто отображаться пользователю вне контроля Python.
Кроме того, если ваши варианты в
opts
совершенно тривиальны, обычно заменяют обычную строку
split()
здесь с
shlex.split()
который понимает, как справляться со строками в кавычках.
.poll()
обновит код возврата.
Пытаться
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()
Кроме того, после .poll()
называется код возврата доступен в объекте как child.returncode
,
Сначала вы должны убедиться, что процесс завершился и код возврата был считан с использованием .wait
метод. Это вернет код. Если вы хотите получить к нему доступ позже, он сохраняется как .returncode
в Popen
объект.
Использовать
process.wait()
после того, как вы позвоните
process.communicate()
.
Например:
import subprocess
process = subprocess.Popen(['ipconfig', '/all'], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
exit_code = process.wait()
print(stdout, stderr, exit_code)
exitcode = data.wait()
, Дочерний процесс будет заблокирован, если он записывает в стандартный вывод / ошибку и / или читает из стандартного ввода, и нет равноправных узлов.
Это сработало для меня. Он также печатает выходные данные, возвращаемые дочерним процессом
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
Пожалуйста, смотрите комментарии.
Код:
import subprocess
class MyLibrary(object):
def execute(self, cmd):
return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True,)
def list(self):
command = ["ping", "google.com"]
sp = self.execute(command)
status = sp.wait() # will wait for sp to finish
out, err = sp.communicate()
print(out)
return status # 0 is success else error
test = MyLibrary()
print(test.list())
Выход:
C:\Users\shita\Documents\Tech\Python>python t5.py
Pinging google.com [142.250.64.78] with 32 bytes of data:
Reply from 142.250.64.78: bytes=32 time=108ms TTL=116
Reply from 142.250.64.78: bytes=32 time=224ms TTL=116
Reply from 142.250.64.78: bytes=32 time=84ms TTL=116
Reply from 142.250.64.78: bytes=32 time=139ms TTL=116
Ping statistics for 142.250.64.78:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 84ms, Maximum = 224ms, Average = 138ms
0