Phủ định nếu điều kiện trong tập lệnh bash


162

Tôi mới sử dụng bash và tôi bị kẹt khi cố gắng phủ nhận lệnh sau:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
        echo "Sorry you are Offline"
        exit 1

Điều này nếu điều kiện trả về đúng nếu tôi kết nối với internet. Tôi muốn nó xảy ra theo cách khác nhưng đặt !bất cứ nơi nào dường như không hoạt động.


3
Bạn đã để nó ở đâu? if ! [[ ...hoạt động
anh chàng kia

1
bạn cũng có thể sử dụng nó theo cách này: wget your_xxxx_params || (tiếng vang "oh oh" && thoát 1)
AKS

2
> gọi một subshell chỉ để xuất ra một lỗi
tijagi

Câu trả lời:


227

Bạn có thể chọn:

if [[ $? -ne 0 ]]; then       # -ne: not equal

if ! [[ $? -eq 0 ]]; then     # -eq: equal

if [[ ! $? -eq 0 ]]; then

! đảo ngược sự trở lại của biểu thức sau, tương ứng.


9
dấu ngoặc kép có cần thiết không? tại sao vậy?
Alexander Mills

1
@AlexanderMills: Có một số cách để làm điều này. Với dấu ngoặc kép hoặc dấu ngoặc đơn hoặc bằng testlệnh:if test $? -ne 0; then
Cyrus

4
Câu trả lời này là không cần thiết. ifmong đợi một câu lệnh là 0 hoặc 1, vì vậy bạn có thể sử dụng chính lệnh đó và đảo ngược nó:if ! wget ...; then ...; fi
Nils Magnus


8

Nếu bạn cảm thấy lười biếng, đây là một phương pháp xử lý các điều kiện ngắn gọn bằng cách sử dụng ||(hoặc) và &&(và) sau thao tác:

wget -q --tries=10 --timeout=20 --spider http://google.com || \
{ echo "Sorry you are Offline" && exit 1; }

8
Trong các tập lệnh thực tế, bạn nên thay đổi &&sau lệnh echo thành a ;. Lý do cho điều này là nếu đầu ra đang được chuyển hướng đến một tệp trên một đĩa đầy đủ, echonó sẽ trả về thất bại và exitsẽ không bao giờ kích hoạt. Đây có lẽ không phải là hành vi bạn muốn.
Điểm_Under

hoặc bạn có thể sử dụng set -evà thất bại echosẽ thoát khỏi tập lệnh bằng mọi cách
Jakub Bochenski

4

Vì bạn đang so sánh các số, bạn có thể sử dụng biểu thức số học , cho phép xử lý các tham số và so sánh đơn giản hơn:

wget -q --tries=10 --timeout=20 --spider http://google.com
if (( $? != 0 )); then
    echo "Sorry you are Offline"
    exit 1
fi

Chú ý thay vì -ne, bạn chỉ có thể sử dụng !=. Trong ngữ cảnh số học, chúng ta thậm chí không phải trả trước $các tham số, nghĩa là,

var_a=1
var_b=2
(( var_a < var_b )) && echo "a is smaller"

hoạt động hoàn toàn tốt Điều này không có nghĩa là $?tham số đặc biệt, mặc dù.

Hơn nữa, vì (( ... ))đánh giá các giá trị khác không thành đúng, nghĩa là có trạng thái trả về 0 cho các giá trị khác không và trạng thái trả về là 1, nếu không, chúng ta có thể rút ngắn thành

if (( $? )); then

nhưng điều này có thể gây nhầm lẫn cho nhiều người hơn các tổ hợp phím được lưu có giá trị.

Cấu (( ... ))trúc có sẵn trong Bash, nhưng không được yêu cầu bởi đặc tả vỏ POSIX (mặc dù được đề cập là có thể mở rộng).

Tất cả điều này đã được nói, tốt hơn hết là tránh $?hoàn toàn theo ý kiến ​​của tôi, như trong câu trả lời của Colecâu trả lời của Steven .



@ DavidC.Rankin Ồ, tôi đã không tìm thấy điều đó! Vì vậy, nó được đề cập như một phần mở rộng, nhưng không bắt buộc. Tôi sẽ sửa đổi.
Benjamin W.

1
Vâng, cái đó luôn luôn có tôi. Nó chắc chắn làm cho cuộc sống dễ dàng hơn trong vỏ:)
David C. Rankin

4

Bạn có thể sử dụng so sánh không bằng nhau -nethay vì -eq:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
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.