Bagaimana cara mendapatkan kode keluar saat menggunakan metode komunikasi subproses Python?

186

Bagaimana cara mengambil kode keluar saat menggunakan subprocessmodul dan communicate()metode Python ?

Kode yang relevan:

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

Haruskah saya melakukan ini dengan cara lain?

CarpeNoctem
sumber

Jawaban:

266

Popen.communicateakan mengatur returncodeatribut ketika selesai (*). Inilah bagian dokumentasi yang relevan:

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).

Jadi Anda bisa melakukannya (saya tidak mengujinya tetapi harus bekerja):

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

(*) Ini terjadi karena cara penerapannya: setelah mengatur utas untuk membaca aliran anak, ia hanya memanggil wait.

Eli Bendersky
sumber
34
Contoh ini membantu saya, tetapi alangkah baiknya jika contoh tidak melakukan pola "impor subproses sebagai sp" mengimpor standar sesuatu sebagai singkatan yang tidak jelas. Meskipun ini memangkas 8 karakter dari kode yang mengikutinya, itu juga membuatnya sulit untuk dipahami dan digunakan kembali.
uglycoyote
16
@uglycoyote Tidak ada aturan yang mengatakan Anda harus menyalin dan menempel. Cukup ketik ulang sesukamu, seperti 4 baris seperti.
Jason C
5
@uglycoyote Anda juga dapat mengeditnya menjadi sesuatu seperti from subprocess import Popendan kemudian gunakan Popensaja subprocess(or sp).Popenyang saya katakan mungkin meningkatkan keterbacaan dan memperpendek baris
Mitch
2
Ya ... harus memanggil process.communicate()dan kemudian menetapkan returncodeke beberapa variabel. Jika tugas dilakukan sebelum memanggil communicate, adalah None.
WesternGun
1
Apakah mungkin untuk menunjukkan kode kembali tanpa mengarahkan pipa? Saya memanggil kode bash dan saya ingin melihat output secara real time di terminal
Nisba
10

Anda harus terlebih dahulu memastikan bahwa proses telah selesai berjalan dan kode kembali telah dibacakan menggunakan .waitmetode ini. Ini akan mengembalikan kode. Jika Anda ingin mengaksesnya nanti, itu disimpan seperti .returncodedalam Popenobjek.

Noufal Ibrahim
sumber
24
.communicate()sudah menunggu subproses untuk mengakhiri.
Mekanik siput
8

.poll() akan memperbarui kode kembali.

Mencoba

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

Selain itu, setelah .poll()dipanggil kode kembali tersedia di objek sebagai child.returncode.

Matthew Vernon
sumber
ketika saya melakukan ini .poll () kosong. Saya harus menjalankan child.communicate () pada baris di atas child.poll () agar ini berfungsi.
NateW
1
Saya pikir Anda bermaksud menggunakan .wait () alih-alih .poll (), sesuai dokumentasi: docs.python.org/3/library/subprocess.html . Perhatikan bahwa .wait () membutuhkan param batas waktu opsional yang bisa nyaman.
gg99
7

exitcode = data.wait(). Proses anak akan diblokir Jika itu menulis ke output standar / kesalahan, dan / atau membaca dari input standar, dan tidak ada rekan.

khachik
sumber
1

Ini berhasil untuk saya. Ini juga mencetak output yang dikembalikan oleh proses anak

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
Chinni Mahesh
sumber