Як отримати код виходу при використанні методу зв'язку підпроцесу Python?


186

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

Відповідний код:

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

Чи варто робити це іншим способом?

Відповіді:


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
Цей приклад мені допоміг, але було б добре, якби приклади не робили схему "імпортування підпроцесу як sp" імпортування чогось стандартного у вигляді незрозумілого абревіатури. Хоча це обрізає 8 символів від коду, що йде за ним, це також ускладнює розуміння та повторне використання.
uglycoyote

16
@uglycoyote Не існує жодного правила, яке говорить про те, що потрібно копіювати та вставляти. Просто введіть його як завгодно, це як 4 схожі лінії.
Джейсон C

5
@uglycoyote ви також можете відредагувати його як щось подібне, from subprocess import Popenа потім просто використовувати, Popenзамість subprocess(or sp).Popenчого, я б сказав, мабуть, збільшує читабельність і скорочує рядки
Мітч

2
Так ... треба зателефонувати, process.communicate()а потім призначити returncodeякусь змінну. Якщо призначення виконано перед викликом communicate, є None.
WesternGun

1
Чи можливо показати зворотний код без перенаправлення труби? Я телефоную баш-коду, і я хотів би побачити вихід в реальному часі в терміналі
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 (), щоб це працювало.
NateW

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.