Trạng thái thoát khác không cho thoát sạch


15

Có thể chấp nhận trả lại mã thoát không bằng 0 nếu chương trình được đề cập chạy đúng không? Ví dụ: giả sử tôi có một chương trình đơn giản (chỉ) thực hiện như sau:

Chương trình có N đối số. Nó trả về mã thoát là min (N, 255). Lưu ý rằng bất kỳ N là hợp lệ cho chương trình.

Một chương trình thực tế hơn có thể trả về các mã khác nhau cho các chương trình được chạy thành công biểu thị những thứ khác nhau. Thay vào đó, các chương trình này có nên viết thông tin này vào một luồng thay vào đó, chẳng hạn như thiết bị xuất chuẩn không?

Câu trả lời:


24

Nó phụ thuộc vào môi trường, nhưng tôi muốn nói rằng đó là phong cách kém.

Các hệ thống giống như Unix có một quy ước mạnh mẽ rằng trạng thái thoát là 0 biểu thị thành công và bất kỳ trạng thái thoát khác không nào cũng biểu thị sự thất bại. Một số, nhưng không phải tất cả, các chương trình phân biệt giữa các loại lỗi khác nhau với các mã thoát khác không; ví dụ grepthường trả về 0 nếu mẫu được tìm thấy, 1 nếu không và 2 (hoặc nhiều hơn) nếu có lỗi như tệp bị thiếu.

Quy ước này có khá nhiều dây cứng vào vỏ Unix. Ví dụ: trong sh, bashvà các shell giống như Bourne khác, ifcâu lệnh coi trạng thái thoát 0 là thành công / đúng và trạng thái thoát không bằng 0 là fail / false:

if your-command
then
    echo ok
else
    echo FAILURE
fi

Tôi tin rằng các quy ước trong MS Windows là tương tự nhau.

Bây giờ chắc chắn không có gì ngăn bạn viết chương trình của riêng bạn sử dụng mã thoát độc đáo, đặc biệt là nếu không có gì khác sẽ tương tác với nó, nhưng lưu ý rằng bạn đang vi phạm một quy ước được thiết lập tốt, và nó có thể quay lại và cắn bạn sau .

Cách thông thường để một chương trình trả về loại thông tin này là in nó ra stdout:

status = $(your-command)
echo Result is $status

7
+1 để giải thích quy ước, cách tiếp cận đó sẽ phá vỡ hầu hết các tập lệnh shell của tôi là tôi đã đặt set -eở đâu đó.
Benjamin Bannier

Tương tự như vậy grep, difftrả về 1 khi tìm thấy sự khác biệt; và> 1 nếu xảy ra lỗi.
7heo.tk

6

Phụ thuộc vào những gì môi trường của bạn mong đợi.

Yêu thích của tôi cho wierdness, từ Wikipedia :

Trong OpenVMS, thành công được biểu thị bằng các giá trị lẻ và thất bại bằng các giá trị chẵn. Giá trị là một số nguyên 32 bit với các trường con: bit điều khiển, số cơ sở, số thông báo và mức độ nghiêm trọng. Các giá trị nghiêm trọng được phân chia giữa thành công (Thành công, Thông tin) và thất bại (Cảnh báo, Lỗi, Gây tử vong).


4

Tôi nghĩ rằng có một tiền lệ nếu mã thoát đang trả lại thông tin có ý nghĩa, có liên quan cho người gọi và định nghĩa thành công không thực sự là nhị phân. Tiền lệ mà tôi nghĩ đến là robocopy trả lại hàng loạt thứ khác nhau tùy thuộc vào những gì đã xảy ra .

Tôi sẽ nói thêm rằng cuối cùng chúng tôi luôn có một số gỡ lỗi vì điều này - hầu hết các tiện ích đều giả sử mã thoát 0 == thành công nên bị bối rối khi robocopy trả về 1 vì nó sao chép nội dung không bằng 0 vì nó không sao chép nội dung nhưng không ' t cũng bị lỗi


2

không trả về 0 để chạy thành công là một ý tưởng tồi, bởi vì nó có thể gây nhầm lẫn cho những người chạy chương trình của bạn. Điều gì sẽ xảy ra nếu một số chạy chương trình của bạn hơn 100 lần với các đầu vào khác nhau và muốn biết có bao nhiêu thất bại hoặc hoàn thành thành công, có một giá trị thành công duy nhất giúp điều này dễ dàng phát hiện ra sự khác biệt hơn là có nhiều giá trị khác nhau.

Nếu bạn có một chương trình có nhiều đường dẫn trả về thành công mà tất cả có thể biểu thị những thứ khác nhau, tôi sẽ nói đó là một dấu hiệu chương trình của bạn được thiết kế kém.


2

Tôi biết một trường hợp tôi nghĩ là chấp nhận được. Tôi biết một khung kiểm tra thoát với tổng số lần kiểm tra thất bại. Vì vậy, ví dụ, nếu người chạy thử hoàn thành mà không có bài kiểm tra thất bại nào thì nó thoát bằng không. Nếu một thử nghiệm thất bại, mặc dù bản thân người chạy thử đã chạy một cách tự do, nó sẽ thoát với một 1. Nếu hai lần thất bại, nó sẽ trả về 2, v.v. Điều này có nghĩa là lên tới 250, có nghĩa là "250 lần thử nghiệm trở lên".

Nó sử dụng mã thoát> 250 để biểu thị lối thoát bất thường.

Trong khi điều này vi phạm quy ước, nó hoạt động tốt trong thực tế.


3
Tôi không nghĩ rằng đây không vi phạm Công ước - thử nghiệm là thành công nếu không có sai sót; bất kỳ mã kết quả khác không chỉ ra các thử nghiệm thất bại.
Bevan

1
Đó là "thoát với trạng thái lỗi để chỉ ra nhiều hơn 0 lỗi" và mặc dù nó có thể vi phạm ngữ nghĩa chung chính xác của trạng thái thoát, nhưng chắc chắn nó không vi phạm quy ước "0 là OK, bất cứ điều gì lớn hơn 0 đều là lỗi" .
Vatine

2

Nó thực sự phụ thuộc vào những gì bạn đang cố gắng truyền đạt với mã. Ví dụ, DB2 trả về 100 nếu không tìm thấy dữ liệu, nhiều giá trị dương khác cho các cảnh báo và giá trị âm cho các lỗi. Oracle làm một cái gì đó tương tự.

Vì vậy, nếu có các trạng thái thành công khác nhau, có thể đáng để sử dụng các giá trị trả về khác nhau.


2

Một ví dụ điển hình: man sa-update (spamassassin)

CHI PHÍ XUẤT KHẨU

  • Mã thoát 0 có nghĩa là đã có bản cập nhật và đã được tải xuống và cài đặt thành công nếu --checkonly không được chỉ định.
  • Mã thoát 1 có nghĩa là không có bản cập nhật mới.
  • Mã thoát gồm 2 nghĩa là ...

Trong trường hợp này, lối ra 1 chỉ đơn giản là một mã thông tin. Tuy nhiên, nếu tôi đã viết mã, tôi sẽ không chọn 1 vì đó thường là lỗi chính.

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.