Hãy xem xét các lệnh
eval false || echo ok
echo also ok
Thông thường, chúng tôi hy vọng điều này sẽ thực thi falsetiện ích và, vì trạng thái thoát là khác không, sau đó thực thi echo okvà echo also ok.
Trong tất cả các POSIX giống như vỏ tôi sử dụng ( ksh93, zsh, bash, dash, OpenBSD ksh, và yash), đây là những gì xảy ra, nhưng mọi thứ trở nên thú vị nếu chúng tôi cho phép set -e.
Nếu set -ecó hiệu lực, OpenBSD shvà kshshell (cả hai đều xuất phát từ pdksh) sẽ chấm dứt tập lệnh khi thực thi eval. Không có vỏ khác làm điều đó.
POSIX nói rằng một lỗi trong một tiện ích tích hợp đặc biệt (chẳng hạn như eval) sẽ khiến lớp vỏ không tương tác chấm dứt. Tôi không hoàn toàn chắc chắn liệu việc thực thi có falsecấu thành "lỗi" hay không (nếu có, nó sẽ không phụ thuộc vào set -ehoạt động).
Cách để giải quyết vấn đề này dường như là đặt evalvỏ phụ,
( eval false ) || echo ok
echo also ok
Câu hỏi đặt ra là liệu tôi có phải làm điều đó trong tập lệnh shell chính xác POSIX-ly hay không, hay đó là một lỗi trong trình bao của OpenBSD? Ngoài ra, "lỗi" trong văn bản POSIX được liên kết ở trên có nghĩa là gì?
Thêm một chút thông tin: Các shell OpenBSD sẽ thực thi echo okcả có và không có set -e trong lệnh
eval ! true || echo ok
Mã ban đầu của tôi trông giống như
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
cái mà sẽ không xuất ra not okkhi string=falsesử dụng shell OpenBSD (nó sẽ chấm dứt) và tôi không chắc nó là do thiết kế, do nhầm lẫn hay do hiểu lầm, hay cái gì khác.
eval falsechấm dứt tập lệnh ngay cả khi đó là một phần của danh sách AND-OR hoặc câu lệnh có điều kiện không? Tôi sẽ không.
set -eđược đặt nếu đó là hành vi chính xác ... Tôi đồng ý rằng việc không chấm dứt trong một tuyên bố có điều kiện là hợp lý.
set -evì vậy `()` là câu trả lời.
eval falsetạo ra một trạng thái khác không, vì vậy tôi dự kiếnset -esẽ chấm dứt tập lệnh tại thời điểm đó. Trong trường hợp!set -ekhông áp dụng như!câu lệnh kiểm tra rõ ràng trạng thái thoát.