2011-02-03 25 views
63

Thông thường, thoát vải ngay khi lệnh run() trả về mã thoát khác. Đối với một số cuộc gọi, tuy nhiên, điều này được mong đợi. Ví dụ: PNGOut trả về mã lỗi 2 khi không thể nén tệp.Tôi có thể nhận các mã lỗi khi sử dụng các lệnh Fabric để chạy() trong một remote shell không?

Hiện tại tôi chỉ có thể phá vỡ giới hạn này bằng cách sử dụng logic vỏ (do_something_that_fails || true hoặc do_something_that_fails || do_something_else), nhưng tôi muốn có thể giữ logic của mình bằng Python đơn giản (như lời hứa của Fabric).

Có cách nào để kiểm tra mã lỗi và phản ứng với mã lỗi thay vì phải lo sợ về Vải và chết không? Tôi vẫn muốn các hành vi mặc định cho các cuộc gọi khác, vì vậy thay đổi hành vi của nó bằng cách sửa đổi môi trường dường như không phải là một lựa chọn tốt (và theo tôi nhớ, bạn chỉ có thể sử dụng nó để cảnh báo thay vì chết).

+2

Trước khi ai đó này đánh dấu một trùng lặp: [câu hỏi này có liên quan] (http://stackoverflow.com/questions/3876936/how-to-continue-the-task-when- vải-đáp-một-lỗi), nhưng như tôi đã nói, tôi muốn _react_ đến lỗi, không bỏ qua chúng. –

+0

Câu trả lời hiện được chấp nhận là ngày. Kể từ tháng 7 năm 2013, đã có một biến môi trường cho phép bạn chỉ định ngoại lệ nào sẽ được đưa ra khi xảy ra lỗi (mặc định là 'SystemExit', không phải là hậu duệ của Ngoại lệ, đó là lý do khiến chương trình của bạn bị hỏng). Xem câu trả lời của tôi: http://stackoverflow.com/a/25293275/901641 – ArtOfWarfare

+0

//, tôi tò mò về cách Invoke sẽ xử lý việc này. –

Trả lời

87

Bạn có thể ngăn hủy trên mã thoát khác không bằng cách sử dụng người quản lý settings bối cảnh và khung cảnh warn_only:

from fabric.api import settings 

with settings(warn_only=True): 
    result = run('pngout old.png new.png') 
    if result.return_code == 0: 
     do something 
    elif result.return_code == 2: 
     do something else 
    else: #print error to user 
     print result 
     raise SystemExit() 

Cập nhật: câu trả lời của tôi là lỗi thời. Xem bình luận bên dưới.

+0

Bạn thậm chí không cần phải kiểm tra return_code, giá trị của kết quả đánh giá là boolean true hoặc false tùy thuộc vào trạng thái thành công của tác vụ.http: //docs.fabfile.org/en/1.7/api/core/operations .html # fabric.operations.run –

+1

Điều này không hoạt động đối với các lỗi hết thời gian chờ. Có hoặc không có "với các thiết lập" hoặc thậm chí với một thử/trừ, Vải vẫn thoát hoàn toàn. – Cerin

+0

-1: Câu trả lời này là ngày - kể từ tháng 7 năm 2013, bạn có thể chỉ định ngoại lệ nào được gọi khi lỗi được gọi. Xem câu trả lời của tôi ở đây: http: // stackoverflow.com/a/25293275/901641 – ArtOfWarfare

4

Dường như gây rối với môi trường câu trả lời.

fabric.api.settings có thể được sử dụng làm trình quản lý ngữ cảnh (với with) để áp dụng cho các câu lệnh riêng lẻ. Giá trị trả về của các cuộc gọi run(), local()sudo() không chỉ là đầu ra của lệnh shell, mà còn có các thuộc tính đặc biệt (return_codefailed) cho phép phản ứng với các lỗi.

Tôi đoán tôi đang tìm kiếm điều gì đó gần gũi hơn với hành vi của subprocess.Popen hoặc xử lý ngoại lệ thông thường của Python.

28

Có, bạn có thể. Chỉ cần thay đổi môi trường abort_exception. Ví dụ:

from fabric.api import settings 

class FabricException(Exception): 
    pass 

with settings(abort_exception = FabricException): 
    try: 
     run(<something that might fail>) 
    except FabricException: 
     <handle the exception> 

Tài liệu trên abort_exceptionhere.

+1

Điều này dường như không cung cấp quyền truy cập vào mã thoát của lệnh. –

+0

@AlanPlum - Bạn có thể nhận được thông báo ngoại lệ ... nhưng bạn nói đúng, tôi không thấy cách nhận mã thoát. – ArtOfWarfare

1

thử này

from fabric.api import run, env 
env.warn_only = True # if you want to ignore exceptions and handle them yurself 

command = "your command" 
x = run(command, capture=True) # run or local or sudo 
if(x.stderr != ""): 
    error = "On %s: %s" %(command, x.stderr) 
    print error 
    print x.return_code # which may be 1 or 2 
    # do what you want or 
    raise Exception(error) #optional 
else: 
    print "the output of %s is: %s" %(command, x) 
    print x.return_code # which is 0 
+2

Tôi đã thử ở trên với kết quả sau: 'TypeError: run() nhận một đối số từ khóa không mong muốn 'capture'' với Fabric 1.10.2 và Paramiko 1.15.2. – DMfll

Các vấn đề liên quan