Thực hiện (exit 1);
là cách đơn giản nhất để kích hoạt một ERR
cái bẫy. Nó cũng sẽ kích hoạt thoát ngay lập tức nếu set -e
có hiệu lực. (Kích hoạt điều kiện lỗi yêu cầu một lệnh thất bại; exit
với giá trị thất bại trong một lớp con làm cho lớp con bị lỗi.)
exit 1;
sẽ không làm những điều đó.
Vì vậy, {(exit 1); exit 1;}
trước tiên có thể được sử dụng để tạo ERR
bẫy, có thể làm điều gì đó hữu ích cho mục đích gỡ lỗi và sau đó chấm dứt tập lệnh với dấu hiệu lỗi.
Nhưng đó không phải là những gì đang diễn ra trong autoconf
các tập tin. autoconf
các tập lệnh dựa vào EXIT
bẫy để dọn sạch các tệp tạm thời được tạo trong quá trình chạy. Hầu hết các shell, bao gồm bash
sẽ đặt trạng thái từ giá trị được cung cấp trong exit
lệnh trước khi gọi EXIT
bẫy. Điều đó có thể cho phép EXIT
bẫy phát hiện xem nó đã được gọi từ một lỗi hay từ chấm dứt bình thường, và nó cũng cho phép nó đảm bảo rằng trạng thái thoát được đặt chính xác vào cuối hoạt động bẫy.
Tuy nhiên, rõ ràng một số vỏ không hợp tác. Đây là một trích dẫn từ autoconf
hướng dẫn :
Một số tập lệnh shell, chẳng hạn như tập lệnh được tạo bởi autoconf
, sử dụng một cái bẫy để dọn sạch trước khi thoát. Nếu lệnh shell cuối cùng thoát với trạng thái khác 0, bẫy cũng thoát với trạng thái khác 0 để kẻ xâm lược có thể biết rằng đã xảy ra lỗi.
Thật không may, trong một số shell, như Solaris /bin/sh
, một bẫy thoát bỏ qua đối số của lệnh thoát. Trong các shell này, một cái bẫy không thể xác định liệu nó được gọi bằng lối thoát đơn giản hay bằng lối thoát 1. Thay vì gọi trực tiếp lối ra, hãy sử dụng AC_MSG_ERROR
macro có cách giải quyết cho vấn đề này.
Cách giải quyết là để đảm bảo rằng $?
có trạng thái thoát trước khi các exit
lệnh được thực thi, do đó nó chắc chắn sẽ có giá trị mà khi EXIT
bẫy được thực thi. Và, thực sự, đó là AC_MSG_ERROR
macro chèn mã tò mò đó, hoàn chỉnh với các dấu ngoặc nhọn.
false
thay vì(exit 1)
?