Tập lệnh Bash với `set -e` không dừng trên lệnh` '& &' '


13

Tôi sử dụng set -eđể dừng tập lệnh bash trên lỗi đầu tiên .

Tất cả đều hoạt động tốt trừ khi tôi sử dụng lệnh với &&:

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

so sánh với:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

Ví dụ đầu tiên vẫn còn vang I'm running! , nhưng thứ hai thì không. Tại sao họ cư xử khác nhau?

CẬP NHẬT. Câu hỏi tương tự: /programming/6930295/set-e-and-short-tests


Bạn mong đợi điều gì xảy ra trong ví dụ đầu tiên?
Flup

@Flup Tôi hy vọng tập lệnh dừng sau khi cdlệnh không thành công
907

1
Xem BashFAQ # 105 để biết một cuộc thảo luận chung về những nơi mà set -ehành vi gây ngạc nhiên.
Charles Duffy

Câu trả lời:


9

Đây là hành vi được ghi lại. Các bash (1) người đàn ông nói, choset -e ,

Shell không thoát nếu lệnh bị lỗi là một phần của danh sách lệnh ngay sau một whilehoặc một untiltừ khóa, một phần của kiểm tra theo các từ ifhoặc elifdành riêng, một phần của bất kỳ lệnh nào được thực thi trong một danh sách &&hoặc|| ngoại trừ lệnh theo lệnh cuối cùng &&hoặc|| , bất kỳ lệnh trong một đường ống nhưng cuối cùng, hoặc nếu giá trị trả về của lệnh đang được đảo ngược với !.
[Nhấn mạnh thêm.]

Đặc tả ngôn ngữ lệnh POSIX Shell xác nhận rằng đây là hành vi chính xác:

Các -ethiết lập sẽ được bỏ qua khi thực hiện danh sách các hợp chất sau while, until, if, hoặcelif từ dành riêng, một đường ống dẫn bắt đầu với !từ dành riêng, hoặc bất kỳ lệnh của AND-OR danh sách khác so với trước.

Mục 2.9.3 Danh sách tài liệu đó xác định

Danh sách AND-OR là một chuỗi gồm một hoặc nhiều đường ống được phân tách bởi các toán tử " &&" và " ||".


9

Các set -e tùy chọn không có tác dụng trong một số tình huống, và đây là hành vi tiêu chuẩn và di động trên POSIX vỏ tuân thủ.


Lệnh thất bại là một phần của đường ống dẫn:

false | true; echo printed

sẽ in printed .

Và chỉ có sự thất bại của chính đường ống được xem xét:

true | false; echo 'not printed'

sẽ không in gì cả.


Lệnh không chạy trong danh sách hợp chất sau while, until, if, eliftừ dành riêng, một đường ống dẫn bắt đầu với !từ dành riêng, hoặc bất kỳ lệnh như một phần của &&hoặc ||danh sách ngoại trừ một lần cuối:

false || true; echo printed

Lệnh cuối cùng vẫn không set -ebị ảnh hưởng:

true && false; echo 'not printed'

Các subshell thất bại trong một lệnh hợp chất:

(false; echo 'not printed') | cat -; echo printed

Cảm ơn bạn! Nó sẽ rõ ràng hơn để sử dụng echo "printed"echo "not_printed"trong các ví dụ của bạn (thay vì echo 1).
907

3
Lưu ý rằng set -egây ra một lối ra (false && true); echo not here, nhưng không vào { false && true; }; echo here, mặc dù YMMV với các vỏ khác nhau và thậm chí các phiên bản khác nhau của cùng một vỏ. Tôi sẽ không chạm set -evào sà lan và thay vào đó sẽ xử lý lỗi thích hợp.
Stéphane Chazelas

1

Tôi đoán là nếu - thì điều kiện tổng thể đánh giá là đúng.

Tôi đã thử

set -e
if cd not_existing_dir
then  echo 123
fi
echo "I'm running! =P"

ai cho

-bash: cd: not_existing_dir: No such file or directory
I'm running! =P

mã lỗi được bắt bởi if condition, do đó bash sẽ không kích hoạt kết thúc thực thi.


Nhưng tôi không sử dụngif ... fi
907

Tôi biết, đây là một ẩn nếu.
Archemar
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.