Zaneguj warunek if w skrypcie bash


162

Jestem nowy w bashu i utknąłem na próbie zanegowania następującego polecenia:

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

Dzieje się tak, jeśli warunek zwraca wartość true, jeśli mam połączenie z Internetem. Chcę, żeby stało się to na odwrót, ale umieszczanie w !dowolnym miejscu nie wydaje się działać.


3
Gdzie to położyłeś? if ! [[ ...działa
ten drugi facet

1
możesz też użyć tego w ten sposób: wget your_xxxx_params || (echo „oh oh” && wyjście 1)
AKS

2
> wywołanie podpowłoki tylko po to, aby wyświetlić błąd
tijagi,

Odpowiedzi:


227

Możesz wybrać:

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

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

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

! odwraca odpowiednio zwrot następującego wyrażenia.


9
czy potrzebne są podwójne nawiasy? dlaczego?
Alexander Mills,

1
@AlexanderMills: Można to zrobić na kilka sposobów. Z podwójnymi lub pojedynczymi nawiasami lub z testpoleceniem:if test $? -ne 0; then
Cyrus

4
Ta odpowiedź jest niepotrzebnie rozwlekła. ifoczekuje instrukcji o wartości 0 lub 1, więc możesz użyć samego polecenia i odwrócić je:if ! wget ...; then ...; fi
Nils Magnus


8

Jeśli czujesz się leniwy, oto zwięzła metoda obsługi warunków za pomocą ||(lub) i &&(i) po operacji:

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

8
W prawdziwych skryptach należy zmienić polecenie &&after echo na a ;. Powodem tego jest to, że jeśli dane wyjściowe są przekierowywane do pliku na pełnym dysku, echozwróci błąd i exitnigdy się nie uruchomi. Prawdopodobnie nie jest to pożądane zachowanie.
Score_Under

lub możesz użyć, set -ea niepowodzenie i echotak wyjdzie ze skryptu
Jakub Bochenski

4

Ponieważ porównujesz liczby, możesz użyć wyrażenia arytmetycznego , które pozwala na prostszą obsługę parametrów i porównanie:

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

Zwróć uwagę, że zamiast tego -nemożesz po prostu użyć !=. W kontekście arytmetycznym nie musimy nawet poprzedzać $parametrów, tj.

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

działa doskonale. Nie dotyczy to jednak $?specjalnego parametru.

Ponadto, ponieważ (( ... ))ocenia wartości niezerowe jako prawdziwe, tj. Zwraca stan 0 dla wartości niezerowych i zwracany stan 1, w przeciwnym razie moglibyśmy skrócić do

if (( $? )); then

ale może to zmylić więcej osób, niż warte są zapisane naciśnięcia klawiszy.

(( ... ))Konstrukt jest dostępny w konsoli, ale nie jest to wymagane w opisie powłoki POSIX (wymienione jako możliwe przedłużenie, choć).

Biorąc to wszystko pod uwagę, lepiej $?moim zdaniem unikać w ogóle, jak w odpowiedzi Cole'a i odpowiedzi Stevena .



@ David C.Rankin Och, nie znalazłem tego! Więc jest wspomniany jako rozszerzenie, ale nie jest wymagane. Poprawię.
Benjamin W.

1
Tak, ten zawsze mnie też dopadł. To z pewnością ułatwia życie w skorupie:)
David C. Rankin

4

Możesz użyć nierównego porównania -nezamiast -eq:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.