2014-05-02 17 views
23

Tôi đang sử dụng:subprocess.check_output Mã trả về

grepOut = subprocess.check_output("grep " + search + " tmp", shell=True) 

Để chạy một lệnh terminal, tôi biết rằng tôi có thể sử dụng một thử/trừ để bắt lỗi nhưng làm thế nào tôi có thể nhận được giá trị của mã lỗi ?

Tôi thấy điều này trên các tài liệu chính thức:

exception subprocess.CalledProcessError 

    Exception raised when a process run by check_call() or check_output() returns a non-zero exit status. 

    returncode 

     Exit status of the child process. 

Nhưng không có ví dụ được đưa và Google đã giúp đỡ không.

+2

* "Google đã không có sự giúp đỡ" *: [mắt xích đầu tiên] (http://stackoverflow.com/a/8235171/4279) (gần như có nó cho thấy 'e. output'), [liên kết thứ hai] (http://stackoverflow.com/a/15316680/4279) là ** đối sánh chính xác ** (nó hiển thị 'e.returncode') cụm từ tìm kiếm:' CalledProcessError'. – jfs

Trả lời

34

Bạn có thể nhận được mã lỗi và kết quả từ ngoại lệ được nêu ra.

Điều này có thể được thực hiện thông qua các trường returncodeoutput.

Ví dụ:

import subprocess 

try: 
    grepOut = subprocess.check_output("grep " + "test" + " tmp", shell=True)      
except subprocess.CalledProcessError as grepexc:                         
    print "error code", grepexc.returncode, grepexc.output 
+1

Cảm ơn chính xác những gì tôi muốn. Nhưng bây giờ tôi tự hỏi, là có một cách để có được một mã trả lại mà không có một thử/ngoại trừ? IE chỉ nhận được mã trả về của check_output, cho dù đó là 0 hay 1 hay khác không quan trọng với tôi và tôi thực sự không cần phải lưu đầu ra. – Juicy

+3

Không sao cả. Thật không may, check_output sẽ luôn ném CalledProcessError miễn là mã lỗi không khác. Điều này có nghĩa là nếu bạn không muốn chương trình đột ngột chấm dứt, bạn sẽ cần một mệnh đề try/except. Tuy nhiên, bạn có thể sử dụng câu lệnh "pass" khi bạn nhận được mệnh đề except nếu bạn không quan tâm đến mã lỗi. – DanGar

21

là có một cách để có được một mã trở lại mà không có một thử/trừ?

check_output tăng ngoại lệ nếu nó nhận được trạng thái thoát khác không vì nó thường có nghĩa là lệnh không thành công. grep có thể trở lại khác không trạng thái thoát ngay cả khi không có lỗi - bạn có thể sử dụng .communicate() trong trường hợp này:

from subprocess import Popen, PIPE 

pattern, filename = 'test', 'tmp' 
p = Popen(['grep', pattern, filename], stdin=PIPE, stdout=PIPE, stderr=PIPE, 
      bufsize=-1) 
output, error = p.communicate() 
if p.returncode == 0: 
    print('%r is found in %s: %r' % (pattern, filename, output)) 
elif p.returncode == 1: 
    print('%r is NOT found in %s: %r' % (pattern, filename, output)) 
else: 
    assert p.returncode > 1 
    print('error occurred: %r' % (error,)) 

Bạn không cần phải gọi một lệnh bên ngoài để dòng bộ lọc, bạn có thể làm điều đó trong tinh khiết Python:

with open('tmp') as file: 
    for line in file: 
     if 'test' in line: 
      print line, 

Nếu bạn không cần đầu ra; bạn có thể sử dụng subprocess.call():

import os 
from subprocess import call 
try: 
    from subprocess import DEVNULL # Python 3 
except ImportError: # Python 2 
    DEVNULL = open(os.devnull, 'r+b', 0) 

returncode = call(['grep', 'test', 'tmp'], 
        stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) 
2

Python 3.5 giới thiệu phương pháp subprocess.run(). Chữ ký trông giống như:

subprocess.run(
    args, 
    *, 
    stdin=None, 
    input=None, 
    stdout=None, 
    stderr=None, 
    shell=False, 
    timeout=None, 
    check=False 
) 

Kết quả trả về là subprocess.CompletedProcess. Trong 3.5, bạn có thể truy cập args, returncode, stdoutstderr từ quá trình được thực thi.

Ví dụ:

>>> result = subprocess.run(['ls', '/tmp'], stdout=subprocess.DEVNULL) 
>>> result.returncode 
0 

>>> result = subprocess.run(['ls', '/nonexistent'], stderr=subprocess.DEVNULL) 
>>> result.returncode 
2 
Các vấn đề liên quan