Nega se la condizione nello script bash


163

Sono nuovo di bash e sono bloccato nel tentativo di annullare il seguente comando:

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

Questa condizione if ritorna vera se sono connesso a Internet. Voglio che accada il contrario, ma mettere !ovunque non sembra funzionare.


3
dove l'hai messo? if ! [[ ...funziona
quell'altro ragazzo il

1
puoi anche usarlo in questo modo: wget your_xxxx_params || (eco "oh oh" && uscita 1)
AKS

2
> chiamare una subshell solo per generare un errore
tijagi,

Risposte:


227

Puoi scegliere:

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

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

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

! inverte il ritorno dell'espressione seguente, rispettivamente.


9
sono necessarie le doppie parentesi? perché?
Alexander Mills,

1
@AlexanderMills: ci sono diversi modi per farlo. Con parentesi doppie o singole o con testcomando:if test $? -ne 0; then
Cyrus

4
Questa risposta è inutile dettagliata. ifsi aspetta una dichiarazione che sia 0 o 1, quindi puoi usare il comando stesso e invertirlo:if ! wget ...; then ...; fi
Nils Magnus


8

Se ti senti pigro, ecco un metodo conciso per gestire le condizioni usando ||(o) e &&(e) dopo l'operazione:

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

8
Negli script della vita reale dovresti cambiare il &&comando after il comando echo in a ;. La ragione di ciò è che se l'output viene reindirizzato a un file su un disco intero, echorestituirà un errore e exitnon si attiverà mai. Questo probabilmente non è il comportamento che desideri.
Score_Under

oppure puoi usarlo set -ee fallire echouscirà comunque dallo script
Jakub Bochenski il

4

Poiché stai confrontando i numeri, puoi utilizzare un'espressione aritmetica , che consente una gestione più semplice dei parametri e del confronto:

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

Nota come, invece -ne, puoi semplicemente usare !=. In un contesto aritmetico, non dobbiamo nemmeno anteporre $ai parametri, ovvero

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

funziona perfettamente. Questo, tuttavia, non si applica al $?parametro speciale.

Inoltre, poiché (( ... ))valuta valori diversi da zero su true, ovvero ha uno stato di restituzione di 0 per valori diversi da zero e uno stato di restituzione di 1 altrimenti, potremmo accorciare a

if (( $? )); then

ma questo potrebbe confondere più persone di quanto valgono le sequenze di tasti salvate.

Il (( ... ))costrutto è disponibile in Bash, ma non richiesto dalla specifica della shell POSIX (menzionata come possibile estensione).

Detto questo, è meglio evitare del $?tutto secondo me, come nella risposta di Cole e nella risposta di Steven .



@ DavidC.Rankin Oh, non l'ho trovato! Quindi è menzionato come estensione, ma non richiesto. Modificherò.
Benjamin W.

1
Sì, anche quello mi ha sempre preso. Rende sicuramente la vita più facile in shell:)
David C. Rankin

4

È possibile utilizzare un confronto disuguale -neanziché -eq:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.