Kỹ thuật cổ điển (siêu nhân vật thoát):
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
Tôi đã đính kèm các tài liệu tham khảo $g
trong dấu ngoặc kép; Đó là cách thực hành tốt, nói chung. Nghiêm túc, các dấu ngoặc đơn không cần thiết bởi vì quyền ưu tiên -a
và -o
làm cho nó chính xác ngay cả khi không có chúng.
Lưu ý rằng các toán tử -a
và -o
toán tử là một phần của đặc tả POSIX test
, hay [
, chủ yếu là để tương thích ngược ( test
ví dụ, vì chúng là một phần của UNIX phiên bản thứ 7), nhưng chúng được đánh dấu rõ ràng là 'lỗi thời' bởi POSIX. Bash (xem các biểu thức điều kiện ) dường như ưu tiên các ý nghĩa cổ điển và POSIX cho -a
và -o
với các toán tử thay thế riêng của nó có các đối số.
Với một số lưu ý, bạn có thể sử dụng [[
toán tử hiện đại hơn , nhưng lưu ý rằng các phiên bản trong Bash và Korn Shell (chẳng hạn) không cần phải giống hệt nhau.
for g in 1 2 3
do
for c in 123 456 789
do
if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]]
then echo "g = $g; c = $c; true"
else echo "g = $g; c = $c; false"
fi
done
done
Ví dụ chạy, sử dụng Bash 3.2.57 trên Mac OS X:
g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false
Bạn không cần trích dẫn các biến [[
như bạn làm [
vì nó không phải là một lệnh riêng biệt theo cùng một cách [
.
Đó không phải là một câu hỏi kinh điển sao?
Tôi đã có thể nghĩ như vậy. Tuy nhiên, có một cách khác, đó là:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
Thật vậy, nếu bạn đọc hướng dẫn 'vỏ di động' cho autoconf
công cụ hoặc các gói liên quan, ký hiệu này - sử dụng ' ||
' và ' &&
' - là những gì họ khuyên dùng. Tôi cho rằng bạn thậm chí có thể đi xa đến mức:
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
Trường hợp các hành động tầm thường như tiếng vang, điều này không phải là xấu. Khi khối hành động được lặp lại là nhiều dòng, việc lặp lại quá đau đớn và một trong những phiên bản trước đó là thích hợp hơn - hoặc bạn cần bọc các hành động thành một chức năng được gọi trong các then
khối khác nhau .
test
([
) chứ không phải bởi shell. Shell chỉ đánh giá trạng thái thoát của[
.