Lệnh nào có nghĩa là không làm gì khác trong một điều kiện ở Bash?


180

Đôi khi, khi tạo điều kiện, tôi cần mã không làm gì cả, ví dụ, ở đây, tôi muốn Bash không làm gì khi $alớn hơn "10", in "1" nếu $anhỏ hơn "5", nếu không, hãy in "2":

if [ "$a" -ge 10 ]
then
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

Điều này làm cho một lỗi mặc dù. Có một lệnh sẽ không làm gì và cũng không làm chậm kịch bản của tôi?

Câu trả lời:


340

Lệnh no-op trong shell là :(dấu hai chấm).

if [ "$a" -ge 10 ]
then
    :
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

Từ hướng dẫn bash :

:(dấu hai chấm)
Không làm gì ngoài việc mở rộng đối số và thực hiện chuyển hướng. Trạng thái trả về bằng không.


3
@SaintHax Không, nó không chạy true. Nó được tích hợp vào vỏ, và không làm gì cả.
Barmar

1
nó được tích hợp sẵn (bạn đúng), nó trả về true (trạng thái 0) giống như true, và khó đọc hơn. Bash là ngôn ngữ DevOps và nếu :được viết bởi ai đó trong nhóm của tôi, tôi sẽ yêu cầu họ thay đổi nó.
SaintHax

3
@SaintHax Nếu ai đó sử dụng truetrong bối cảnh không có điều kiện, tôi sẽ yêu cầu họ thay đổi nó. if truelà tốt, then truecó vẻ sai.
Barmar

1
Tất nhiên, bạn chỉ có thể viết lại mã để sử dụng if ! condition; then do something; fithay vì if condition; then :; else do something; fi.
Barmar

Tôi đồng ý với bạn. Ví dụ này có thể được viết nếu / elif / khác sử dụng các điều kiện ghép và sẽ tốt hơn.
SaintHax

38

Bạn có thể chỉ cần sử dụng truelệnh:

if [ "$a" -ge 10 ]; then
    true
elif [ "$a" -le 5 ]; then
    echo "1"
else
    echo "2"
fi

Một cách khác, trong trường hợp ví dụ của bạn (nhưng không nhất thiết ở mọi nơi) là sắp xếp lại if / other:

if [ "$a" -le 5 ]; then
    echo "1"
elif [ "$a" -lt 10 ]; then
    echo "2"
fi

8
Nếu bạn không kiểm tra kết quả cả hai truefalsethực sự không có liên quan đến kịch bản, nhưng về nguyên tắc, chúng có thể rẽ nhánh trong một số shell chấp nhận cú pháp này nên có lẽ :tốt hơn.
dmckee --- ex-moderator mèo con

3
Câu hỏi được gắn thẻ bash. Trong bash, truefalseđược xây dựng. Đối với vỏ cũ, true, false, và thậm chí :có thể là lệnh bên ngoài (mặc dù bạn có thể sẽ thấy sau này chỉ có ở rất vỏ cũ).
Keith Thompson

6
Tôi thích :đơn giản hơn vì nó rõ ràng hơn ý định là gì
Freedom_Ben

9

Mặc dù tôi không trả lời câu hỏi ban đầu về lệnh no-op, nhưng nhiều vấn đề (nếu không phải là hầu hết) khi người ta có thể nghĩ rằng " trong nhánh này tôi không phải làm gì " có thể bỏ qua bằng cách đơn giản cấu trúc lại logic để nhánh này giành chiến thắng xảy ra

Tôi cố gắng đưa ra một quy tắc chung bằng cách sử dụng ví dụ OP

không làm gì khi $ a lớn hơn "10", in "1" nếu $ a nhỏ hơn "5", nếu không, hãy in "2"

chúng ta phải tránh một chi nhánh $acó hơn 10, vì vậy$a < 10 một điều kiện chung có thể được áp dụng cho mọi điều kiện khác, sau đây.

Nói chung, khi bạn nói không làm gì khi X , thì hãy viết lại nó như tránh một nhánh trong đó X . Thông thường bạn có thể làm cho việc tránh xảy ra bằng cách đơn giản phủ định X và áp dụng nó cho tất cả các điều kiện khác.

Vì vậy, ví dụ OP với quy tắc được áp dụng có thể được cơ cấu lại như sau:

if [ "$a" -lt 10 ] && [ "$a" -le 5 ]
then
    echo "1"
elif [ "$a" -lt 10 ]
then
    echo "2"
fi

Chỉ là một biến thể của ở trên, kèm theo mọi thứ trong $a < 10điều kiện:

if [ "$a" -lt 10 ]
then
    if [ "$a" -le 5 ]
    then
        echo "1"
    else
        echo "2"
    fi
fi

(Đối với ví dụ cụ thể này, tái cấu trúc @Flimzys chắc chắn tốt hơn, nhưng tôi muốn đưa ra một quy tắc chung cho tất cả những người tìm kiếm cách không làm gì cả.)


5
Một lý do mà ai đó có thể muốn không có là khi ban đầu cấu trúc mã với ý tưởng rằng người ta sẽ thêm "thêm một cái gì đó ở đây sau" mà không có tác dụng phụ vô tình. Ví dụ: nếu một người đang đặt if-then-other-fi trong .bashrc, nếu bạn đặt echo "put stuff here"nó sẽ phá vỡ một số sử dụng không đăng nhập (ví dụ: scp bị hỏng) và chỉ khoảng trắng / bình luận gây ra lỗi thời gian chạy.
Rệp
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.