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.

Sudh33ra
quelle
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.

Cyrus
quelle
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
87

Besser

if ! wget -q --spider --tries=10 --timeout=20 google.com
then
  echo 'Sorry you are Offline'
  exit 1
fi
Steven Penny
quelle
1
Wichtig: !Lassen Sie zwischen dem und dem folgenden Befehl ein Leerzeichen, da Sie sonst eine Verlaufserweiterung durchführen. unix.stackexchange.com/questions/3747/…
Roland
2
Steven, warum hast du nur einen Ruf?
Roland
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; }
Cole Tierney
quelle
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 .

Benjamin W.
quelle
Bist du dir sicher (( ... ))? POSIX Programmers Reference - Zusammengesetzte Befehle
David C. Rankin
@ 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
Davidhigh
quelle