Làm thế nào để có được mã thoát khi sử dụng phương thức giao tiếp của quy trình con Python?


185

Làm cách nào để truy xuất mã thoát khi sử dụng subprocessmô-đun của Python và communicate()phương thức?

Mã liên quan:

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

Tôi có nên làm điều này theo cách khác?

Câu trả lời:


264

Popen.communicatesẽ đặt returncodethuộc tính khi hoàn thành (*). Đây là phần tài liệu liên quan:

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

Vì vậy, bạn chỉ có thể làm (Tôi đã không kiểm tra nhưng nó sẽ hoạt động):

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

(*) Điều này xảy ra do cách thức triển khai: sau khi thiết lập các luồng để đọc các luồng của trẻ, nó chỉ gọi wait.


33
Ví dụ này đã giúp tôi, nhưng sẽ rất tuyệt nếu các ví dụ không thực hiện mô hình "nhập quy trình con dưới dạng sp" của việc nhập một cái gì đó tiêu chuẩn dưới dạng viết tắt tối nghĩa. Mặc dù điều này loại bỏ 8 ký tự theo mã, nhưng nó cũng gây khó khăn cho việc hiểu và sử dụng lại.
uglycoyote

16
@uglycoyote Không có quy tắc nào nói rằng bạn phải sao chép và dán. Chỉ cần gõ lại nó theo cách bạn muốn, nó giống như 4 dòng.
Jason C

5
@uglycoyote bạn cũng có thể chỉnh sửa nó thành một cái gì đó tương tự from subprocess import Popenvà sau đó chỉ cần sử dụng Popenthay vì subprocess(or sp).Popentôi có thể tăng khả năng đọc và rút ngắn các dòng
Mitch

2
Vâng ... phải gọi process.communicate()và sau đó gán returncodecho một số biến. Nếu bài tập được thực hiện trước khi gọi communicate, là None.
WesternGun

1
Có thể hiển thị mã trả lại mà không cần chuyển hướng đường ống? Tôi đang gọi mã bash và tôi muốn xem đầu ra trong thời gian thực trong thiết bị đầu cuối
Nisba

9

Trước tiên bạn nên đảm bảo rằng quy trình đã hoàn tất chạy và mã trả về đã được đọc ra bằng .waitphương thức. Điều này sẽ trả lại mã. Nếu bạn muốn truy cập vào nó sau, nó sẽ được lưu trữ như .returncodetrong Popenđối tượng.


24
.communicate()đã chờ quá trình con kết thúc.
Ốc cơ khí

8

.poll() sẽ cập nhật mã trả về.

Thử

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

Ngoài ra, sau khi .poll()được gọi là mã trả về có sẵn trong đối tượng như child.returncode.


khi tôi làm điều này .poll () là trống rỗng. Tôi đã phải chạy child.c truyền thông () trong dòng trên child.poll () để làm việc này.
NateW

1
Tôi nghĩ rằng bạn có nghĩa là để sử dụng .wait () thay vì .poll (), theo tài liệu: docs.python.org/3/library/subprocess.html . Lưu ý rằng .wait () mất một tham số thời gian chờ tùy chọn có thể thuận tiện.
gg99

7

exitcode = data.wait(). Quá trình con sẽ bị chặn Nếu nó ghi vào đầu ra / lỗi tiêu chuẩn và / hoặc đọc từ đầu vào tiêu chuẩn và không có đồng nghiệp.


1

Điều này làm việc cho tôi. Nó cũng in kết quả đầu ra được trả về bởi tiến trình con

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.