Thoát mã trong Python


207

Tôi nhận được một tin nhắn nói script xyz.py returned exit code 0. Điều đó có nghĩa là gì?

Mã thoát trong Python có nghĩa là gì? Có bao nhiêu cái Những cái nào là quan trọng?


1
Bạn đang thấy tin nhắn này ở đâu?
Jeremy Cantrell

1
@Jeremy Ở dưới cùng của PythonWin.
sundeep

Câu trả lời:


223

Những gì bạn đang tìm kiếm trong kịch bản là các cuộc gọi đến sys.exit(). Đối số cho phương thức đó được trả về môi trường dưới dạng mã thoát.

Rất có khả năng tập lệnh không bao giờ gọi phương thức thoát và 0 là mã thoát mặc định.


12
Không chắc chắn chút nào. Trong Unix / Linux, tiêu chuẩn là: exit 0 trong trường hợp mọi thứ đều ổn. Nhập một lệnh, sau đó lặp lại $?: Nếu bạn đọc 0, nó sẽ trả về mà không gặp lỗi. Ý tưởng là để có các bài kiểm tra tiêu chuẩn. Nếu mã xyz.py không gặp phải bất kỳ lỗi nào, nó sẽ trả về 0!
Bruno von Paris

1
Nếu bạn muốn thay đổi mã thoát, muốn thoát sạch bằng cách sử dụng nội dung thoát, hãy xem câu trả lời này
vidstige

101

Từ tài liệu chosys.exit :

Đối số tùy chọn arg có thể là một số nguyên cho trạng thái thoát (mặc định là 0) hoặc một loại đối tượng khác. Nếu nó là một số nguyên, số 0 được coi là chấm dứt thành công và bất kỳ giá trị khác nào được coi là chấm dứt bất thường bởi các vỏ và tương tự. Hầu hết các hệ thống yêu cầu nó phải nằm trong phạm vi 0-127 và tạo ra kết quả không xác định theo cách khác. Một số hệ thống có một quy ước để gán ý nghĩa cụ thể cho các mã thoát cụ thể, nhưng chúng thường không được phát triển; Các chương trình Unix thường sử dụng 2 cho các lỗi cú pháp dòng lệnh và 1 cho tất cả các loại lỗi khác.

Một ví dụ trong đó mã thoát được sử dụng là trong các kịch bản shell. Trong bash, bạn có thể kiểm tra biến đặc biệt $?cho trạng thái thoát cuối cùng:

me@mini:~$ python -c ""; echo $?
0
me@mini:~$ python -c "import sys; sys.exit(0)"; echo $?
0
me@mini:~$ python -c "import sys; sys.exit(43)"; echo $?
43

Cá nhân tôi cố gắng sử dụng mã thoát mà tôi tìm thấy /usr/include/asm-generic/errno.h(trên hệ thống Linux), nhưng tôi không biết liệu đây có phải là điều đúng hay không.


3
Từ một bài đăng khác, tôi tìm thấy liên kết này: tldp.org/LDP/abs/html/exitcodes.html Có thể hữu ích. :)
Eigir

9
errno.h thường dành cho mã thoát lệnh gọi chức năng. Nỗ lực chuẩn hóa mã thoát chương trình đã dẫn đến /usr/include/sysexits.h có mặt trên hầu hết các hệ thống POSIX.
mpounsett

1
Thật tốt khi biết rằng "Các chương trình Unix thường sử dụng 2 cho các lỗi cú pháp dòng lệnh"!
dantiston

2
@dantiston Đồng tình . Người ủng hộ Gentoo nhuộm lông cứng, nhưng tôi chưa bao giờ biết rằng ... cho đến ngày định mệnh này. ( Sự xấu hổ của tôi kết thúc ngay bây giờ. ) Liên quan, lưu ý rằng grepphá vỡ xu hướng này bằng cách thoát ra 1khi không có dòng nào khớp và 2trên các lỗi thực tế. Cảm ơn rất nhiều, Stallman.
Cecil Curry

32

Đối với bản ghi, bạn có thể sử dụng mã thoát chuẩn POSIX được xác định tại đây .

Thí dụ:

import sys, os

try:
    config()
except:
    sys.exit(os.EX_CONFIG) 
try:
    do_stuff()
except:
    sys.exit(os.EX_SOFTWARE)
sys.exit(os.EX_OK) # code 0, all ok

3
Theo các tài liệu này chỉ có trên các hệ điều hành Unix nên nó không hoàn toàn di động.
phượng hoàng

1
Nếu bạn muốn mã POSIX di động khả dụng trên tất cả các hệ điều hành, hãy xem exitstatusgói PyPI.
phượng hoàng

1
Toàn bộ gói đó là 0 cho thành công và 1 cho thất bại.
Pavel Minaev

25

Có một errnomô-đun xác định mã thoát tiêu chuẩn:

Ví dụ: Quyền bị từ chối là mã lỗi 13 :

import errno, sys

if can_access_resource():
    do_something()
else:
    sys.exit(errno.EACCES)

36
Điều này là không đúng. Những lỗi này không có ý định được sử dụng làm mã thoát quy trình. Đây là các mã lỗi cấp thấp dự định sẽ được sử dụng nội bộ trong các chương trình, cụ thể là các mã được viết bằng ngôn ngữ C. Đối với Python, sử dụng ngoại lệ bất cứ khi nào có thể.
SvdB

2
Bạn đúng. Chúng được sử dụng trong nội bộ. Nhưng bạn thường không đưa ra ngoại lệ ở cấp độ người dùng cuối. Bạn sử dụng sys.exit (x) với x là số nguyên bạn chọn tùy ý. Nhưng bạn có thể sử dụng những người bắt đầu với EX_ và được xác định trong mô-đun 'os'. Giống như os.EX_OK hoặc os.EX_IOERR
Oli

2
Xin lỗi, nhưng tôi cũng bỏ phiếu này vì nó sai. Mã trạng thái thoát và số lỗi không thể thay thế / bổ sung. Sử dụng ví dụ đã cho, quyền của từ chối đã từ chối, có mã lỗi là 13 (theo errnoerrno.h ), nhưng mã trạng thái thoát là 77 (theo ossysexits.h ). Các chương trình phát ra cái trước là không chuẩn ( de facto vel jure ) và sẽ không chơi tốt với những cái khác mong đợi cái sau.
Đánh dấu G.

14

Mã thoát 0 thường có nghĩa là "không có gì sai ở đây." Tuy nhiên, nếu lập trình viên của kịch bản không tuân theo quy ước, bạn có thể phải tham khảo nguồn để xem ý nghĩa của nó. Thông thường giá trị khác không được trả về dưới dạng mã lỗi.


6

Câu trả lời là "Phụ thuộc vào ý nghĩa của mã thoát"

Tuy nhiên, trong hầu hết các trường hợp, điều này có nghĩa là "Mọi thứ đều ổn"


Tôi thích POSIX:

Vì vậy, trên vỏ, tôi sẽ gõ:

python script.py && echo 'OK' || echo 'Not OK'

Nếu kịch bản python của tôi gọi sys.exit(0)shell trả về 'OK'

Nếu tập lệnh python của tôi gọi sys.exit(1)(hoặc bất kỳ số nguyên khác không), shell trả về 'Không ổn'

Công việc của bạn là phải thông minh với trình bao và đọc tài liệu (hoặc nguồn) cho tập lệnh của bạn để xem mã thoát có nghĩa là gì.


Chỉ để hoàn chỉnh, 'Không ổn' sẽ được in nếu tập lệnh Python phát sinh lỗi HOẶC có lỗi cú pháp.
Shital Shah

5

Các lệnh hệ điều hành có mã thoát. Hãy tìm mã thoát linux để xem một số tài liệu về điều này. Shell sử dụng mã thoát để quyết định xem chương trình có hoạt động không, có vấn đề hay không. Có một số nỗ lực để tạo mã thoát tiêu chuẩn (hoặc ít nhất là thường được sử dụng). Xem bài đăng Advanced Shell Script này .



4

Các mã thoát chỉ có ý nghĩa theo sự phân công của tác giả kịch bản. Truyền thống Unix là mã thoát 0 có nghĩa là 'thành công', bất cứ điều gì khác là thất bại. Cách duy nhất để chắc chắn mã thoát cho một tập lệnh đã cho là gì để kiểm tra chính tập lệnh đó.


4

Tôi khuyên bạn nên tắt máy sạch với lối ra (0) dựng sẵn thay vì sử dụng sys.exit ()

Tôi không chắc đây có phải là lời khuyên tốt không.

Các tài liệu rất được đề cập đọc:

Mô-đun trang web (được nhập tự động trong khi khởi động, ngoại trừ nếu tùy chọn dòng lệnh -S được cung cấp) thêm một số hằng vào không gian tên tích hợp. Chúng rất hữu ích cho trình thông dịch tương tác và không nên được sử dụng trong các chương trình .

Sau đó:

thoát (mã = Không có)

Các đối tượng mà khi được in, hãy in một thông báo như sử dụng Thoát () hoặc Ctrl-D (tức là EOF) để thoát ra, và khi được gọi, hãy nâng SystemExit bằng mã thoát được chỉ định.

Nếu chúng ta so sánh nó với tài liệu sys.exit () , thì nó sử dụng cùng một cơ chế tạo ra một SystemExitngoại lệ.


2

Mã thoát trong nhiều ngôn ngữ lập trình là tùy thuộc vào lập trình viên. Vì vậy, bạn phải xem mã nguồn chương trình của bạn (hoặc thủ công). Zero thường có nghĩa là "mọi thứ đều ổn".


-2

Để cho phép các trình xử lý ngoại lệ và các thứ khác thực thi, tôi khuyên bạn nên tắt máy với phần exit(0)dựng sẵn thay vì sử dụng sys.exit()làm chấm dứt quá trình đột ngột.


Vì vậy, sự khác biệt là gì? Thông tin đó lấy từ đâu? Bạn có nghĩa là việc thực hiện các trình xử lý "tại lối ra" hoặc chính xác những gì bạn đang đề cập đến? SystemExitxuất hiện để được nâng lên một trong hai cách.
0xC0000022L

mm, tôi nhầm lẫn với nó os._exit, cả hai dường như tăng lên SystemExit.
vidstige

1
Sai: sys.exit() không tắt máy sạch sẽ, giống như exit(). Cả hai đều làm cùng một điều: nêu ra một SystemExitngoại lệ. Trên thực tế, exit()có nghĩa là cho các phiên tương tác, không phải các kịch bản, vì vậy về mặt khái niệm sys.exit() chỉ định. Bạn có thể nhầm lẫn với os._exit(), đó là một trong đó chấm dứt đột ngột.
MestreLion
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.