Có hai vấn đề liên quan ở đây.
Đầu tiên, câu hỏi của OP, Tại sao 0 là đúng nhưng sai là 1 trong shell? và thứ hai, tại sao các ứng dụng trả về 0 cho thành công và khác 0 cho thất bại?
Để trả lời câu hỏi của OP, chúng ta cần hiểu câu hỏi thứ hai. Nhiều câu trả lời cho bài đăng này đã mô tả rằng đây là một quy ước và đã liệt kê một số điều tốt đẹp mà quy ước này mang lại. Một số điều tốt đẹp này được tóm tắt dưới đây.
Tại sao các ứng dụng trả về 0 cho thành công và khác 0 cho thất bại?
Mã gọi một hoạt động cần biết hai điều về trạng thái thoát của hoạt động. Đã thoát hoạt động thành công? [* 1] Và nếu hoạt động không thoát thành công tại sao hoạt động thoát không thành công? Bất kỳ giá trị nào cũng có thể được sử dụng để biểu thị thành công. Nhưng số 0 thuận tiện hơn bất kỳ số nào khác vì nó có thể di động giữa các nền tảng. Tóm tắt câu trả lời của xibo cho câu hỏi này vào ngày 16 tháng 8 năm 2011:
Zero không phụ thuộc vào mã hóa.
Nếu chúng ta muốn lưu trữ một (1) trong một từ số nguyên 32 bit, câu hỏi đầu tiên sẽ là "từ big-endian hay little-endian từ?", Tiếp theo là "bao lâu thì các byte tạo ra một từ little-endian? ", trong khi số 0 sẽ luôn giống nhau.
Ngoài ra, cần phải mong đợi rằng một số người biến lỗi thành char hoặc short tại một số thời điểm, hoặc thậm chí là nổi. (int) ((char) ENOLCK) không phải là ENOLCK khi ký tự không dài ít nhất 8 bit (các máy ký tự ASCII 7 bit được UNIX hỗ trợ), trong khi (int) ((char) 0) là 0 độc lập với chi tiết kiến trúc của char.
Khi đã xác định được rằng 0 sẽ là giá trị trả về cho sự thành công, thì việc sử dụng bất kỳ giá trị nào khác 0 cho sự thất bại là rất hợp lý. Điều này cho phép nhiều mã thoát để trả lời câu hỏi tại sao hoạt động không thành công.
Tại sao 0 là true nhưng false là 1 trong shell?
Một trong những cách sử dụng cơ bản của shell là tự động hóa các quy trình bằng cách viết kịch bản cho chúng. Thông thường, điều này có nghĩa là gọi một hoạt động và sau đó thực hiện điều gì đó khác có điều kiện dựa trên trạng thái thoát của hoạt động. Philippe A. đã giải thích một cách độc đáo trong câu trả lời của mình cho bài đăng này rằng
Trong bash và trong unix shell nói chung, giá trị trả về không phải là boolean. Chúng là các mã thoát số nguyên.
Sau đó, điều cần thiết là phải diễn giải trạng thái thoát của các hoạt động này dưới dạng giá trị boolean. Có ý nghĩa khi ánh xạ 0
trạng thái thoát thành công ( ) thành true và bất kỳ trạng thái thoát nào khác 0 / thất bại thành false. Làm điều này cho phép thực hiện có điều kiện các lệnh shell chuỗi.
Đây là một ví dụ mkdir deleteme && cd $_ && pwd
. Bởi vì shell diễn giải 0 là true, lệnh này hoạt động thuận tiện như mong đợi. Nếu shell diễn giải 0 là false thì bạn phải đảo ngược trạng thái thoát đã diễn giải cho mỗi thao tác.
Nói tóm lại, sẽ vô nghĩa nếu shell diễn giải 0 là false theo quy ước rằng các ứng dụng trả về 0 cho trạng thái thoát thành công.
[* 1]: Có, nhiều khi các phép toán cần trả lại nhiều hơn một thông báo thành công đơn giản nhưng điều đó nằm ngoài phạm vi của chuỗi này.
Xem thêm Phụ lục E trong Hướng dẫn Viết mã Bash Nâng cao