Negieren Sie die Bedingung im Bash-Skript


162

Ich bin neu in Bash und kann nicht versuchen, den folgenden Befehl zu negieren:

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

Diese if-Bedingung gibt true zurück, wenn ich mit dem Internet verbunden bin. Ich möchte, dass es umgekehrt passiert, aber !irgendwo zu platzieren scheint nicht zu funktionieren.


3
Wo hast du es hingelegt? if ! [[ ...funktioniert
dieser andere Typ

1
Sie können es auch folgendermaßen verwenden: wget your_xxxx_params || (Echo "oh oh" && Ausfahrt 1)
AKS

2
> Aufruf einer Subshell, nur um einen Fehler
auszugeben

Antworten:


227

Du kannst wählen:

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

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

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

! invertiert die Rückgabe des folgenden Ausdrucks.


9
sind die doppelten Klammern notwendig? warum ist das so?
Alexander Mills

1
@AlexanderMills: Es gibt verschiedene Möglichkeiten, dies zu tun. Mit doppelten oder einfachen Klammern oder mit testBefehl:if test $? -ne 0; then
Cyrus

4
Diese Antwort ist unnötig ausführlich. iferwartet eine Anweisung, die entweder 0 oder 1 ist, so dass Sie den Befehl selbst verwenden und ihn invertieren können:if ! wget ...; then ...; fi
Nils Magnus


8

Wenn Sie sich faul fühlen, finden Sie hier eine knappe Methode zur Behandlung von Bedingungen mit ||(oder) und &&(und) nach der Operation:

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

8
In realen Skripten sollten Sie &&den Befehl nach dem Echo in a ändern ;. Der Grund dafür ist, dass, wenn die Ausgabe in eine Datei auf einer vollständigen Festplatte umgeleitet wird, der echoFehler zurückgegeben wird und der exitniemals ausgelöst wird. Dies ist wahrscheinlich nicht das gewünschte Verhalten.
Score_Under

oder Sie können verwenden set -eund fehlschlagen echowird das Skript trotzdem
beenden

4

Da Sie Zahlen vergleichen, können Sie einen arithmetischen Ausdruck verwenden , der eine einfachere Handhabung von Parametern und einen einfacheren Vergleich ermöglicht:

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

Beachten -neSie, dass Sie stattdessen einfach verwenden können !=. In einem arithmetischen Kontext müssen wir nicht einmal $Parametern voranstellen , dh

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

funktioniert einwandfrei. Dies gilt nicht für die$? speziellen Parameter.

Da ferner (( ... ))Nicht-Null-Werte als wahr ausgewertet werden, dh einen Rückgabestatus von 0 für Nicht-Null-Werte und ansonsten einen Rückgabestatus von 1 haben, könnten wir auf verkürzen

if (( $? )); then

Dies könnte jedoch mehr Menschen verwirren, als die gespeicherten Tastenanschläge wert sind.

Das (( ... ))Konstrukt ist in Bash verfügbar, wird jedoch von der POSIX-Shell-Spezifikation nicht benötigt (wird jedoch als mögliche Erweiterung erwähnt).

Dies alles ist $?meiner Meinung nach besser zu vermeiden , wie in Coles Antwort und Stevens Antwort .



@ DavidC.Rankin Oh, das habe ich nicht gefunden! Es wird also als Erweiterung erwähnt, ist aber nicht erforderlich. Ich werde ändern.
Benjamin W.

1
Ja, das hat mich immer auch erwischt. Es macht das Leben in der Muschel sicher einfacher:)
David C. Rankin

4

Sie können einen ungleichen Vergleich verwenden, -neanstatt -eq:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.