Як отримати код виходу при використанні методу зв'язку підпроцесу 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 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.


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.