Tôi thấy hành vi tương tự cho vòng lặp bên dưới như vòng lặp với while [ 1 ]
. Tại sao lại như vậy?
while [ 0 ]; do
echo "hello"
done
Tôi thấy hành vi tương tự cho vòng lặp bên dưới như vòng lặp với while [ 1 ]
. Tại sao lại như vậy?
while [ 0 ]; do
echo "hello"
done
Câu trả lời:
Dấu ngoặc đơn trong shell là từ đồng nghĩa với test
(lệnh riêng hoặc vỏ được tích hợp sẵn), do đó [ 0 ]
có nghĩa tương tự như test 0
. test
là để thực hiện so sánh và kiểm tra các thuộc tính của tệp, như bạn có thể đọc trong trang chủ của nó. Khi nó không được đưa ra một biểu thức trông giống như một phép so sánh, kiểm tra tệp hoặc một trong các thao tác khác mà nó có thể thực hiện, thay vào đó, nó sẽ kiểm tra nếu có đối số và một chuỗi không trống. Không 0
hoặc 1
là đầu vào thực sự thích hợp để kiểm tra, và vì kiểm tra chuỗi không trống chỉ đơn giản là thành công và vòng lặp while của bạn mãi mãi.
Bạn có thể muốn thử thay thế
while false; do
echo "hello"
done
có thể thay thế false
bằng true
. Hoặc có thể những gì bạn muốn là sử dụng (( ))
:
while (( 0 )); do
echo "hello"
done
Điều này sẽ hành xử giống như hầu hết các ngôn ngữ, trong đó 0 có nghĩa là thất bại / sai và 1 có nghĩa là thành công / đúng.
0
và 1
không phải là các chuỗi rỗng. Các lập trình viên shell mới thường viết if [ 1=2 ]
thay vì if [ 1 = 2 ]
và tự hỏi tại sao cái trước luôn luôn đúng. Điều này đúng bởi vì nó là một đối số duy nhất và không phải là một chuỗi rỗng.
Giá trị 0 ở đây không hoạt động như một hằng số, mà là một chuỗi ký tự. Các xét nghiệm này đều tương đương với hiệu quả của việc tạo ra trạng thái chấm dứt thành công:
[ A ]
[ "XYZ" ]
[ 0 ]
những điều này tạo ra một trạng thái chấm dứt không thành công:
[ ]
[ "" ]
có một đối số không trống, đánh giá là đúng logic. Điều này cho phép bạn làm những việc như:
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
Biến UNDER_NUCLEAR_ATTACK
được đặt thành bất kỳ giá trị không trống nào để chỉ đúng, hoặc không được đặt hoặc trống để biểu thị sai.
Chúng ta có thể áp dụng !
toán tử để đảo ngược logic:
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
Để đánh giá một điều kiện số, bạn phải sử dụng các toán tử kiểm tra số:
while [ $A -gt $B ] ; do ...
Nếu A
và B
chứa các chuỗi trông giống như số nguyên thập phân, chúng được so sánh như số và nếu A
lớn hơn B
, vòng lặp sẽ thực thi. Vì vậy, giả sử rằng đó UNDER_NUCLEAR_ATTACK
không phải là một boolean kiểu chuỗi trống hoặc không trống, mà thực sự là một boolean số là 0
(sai) hoặc một số giá trị khác (true). Trong trường hợp đó, chúng tôi sẽ viết bài kiểm tra như thế này:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
Một if / then xây dựng kiểm tra xem trạng thái thoát của danh sách các lệnh là 0 (vì 0 có nghĩa là "thành công" theo quy ước UNIX) và nếu vậy, thực thi một hoặc nhiều lệnh.
Nói tóm lại, bạn đang trả về kết quả kiểm tra bằng không.
[
chỉ nhận được một đối số (tất nhiên không bao gồm ]
), nó sẽ thoát với trạng thái 0 nếu đối số không trống, khác không nếu nó là. Vì vậy, ví dụ, [ 1 ]
cũng sẽ trả về mã thoát của 0
.
[ ]
(không có đối số) và[ "" ]
(với một đối số trống duy nhất) không thành công.