2014-10-20 14 views
71

Sono nuovo di colpire e mi sono bloccato a cercare di negare il seguente comando:Nega se la condizione in script bash

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

Questo se la condizione restituisce true se sono connesso a Internet. Voglio che succeda il contrario, ma mettere lo ! ovunque non sembra funzionare.

+1

Dove l'hai messo? 'se! [[... 'funziona –

+1

puoi anche usarlo in questo modo: wget your_xxxx_params || (echo "oh oh" && exit 1) –

+2

> chiamare una subshell solo per emettere un errore – tijagi

risposta

91

È possibile scegliere:

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

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

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

! inverte il ritorno della seguente espressione, rispettivamente.

+6

sono necessarie le doppie parentesi? perché? –

+0

@AlexanderMills: ci sono diversi modi per farlo. Con parentesi doppie o singole o con il comando 'test':' se test $? -ne 0; then' – Cyrus

+0

Questa risposta non è autonoma. Eiter spiega cosa! è e fa o fornisce un collegamento alla documentazione. – ManuelSchneid3r

4

È possibile utilizzare impari confronto -ne invece di -eq:

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

Se vi sentite pigri, ecco un metodo concisa delle condizioni di movimentazione usando || (o) e && (e) dopo l'operazione:

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

Negli script di vita reale dovresti cambiare il comando '&&' dopo il comando echo in un ';'. Il motivo è che se l'output viene reindirizzato su un file su un intero disco, l'echo restituirà un errore e l'uscita non verrà mai attivata. Questo probabilmente non è il comportamento che desideri. –

+0

oppure puoi usare 'set -e' e fallendo' echo' uscirà comunque dallo script –

44

Meglio

if ! wget -q --spider --tries=10 --timeout=20 google.com 
then 
    echo 'Sorry you are Offline' 
    exit 1 
fi 
4

Dal momento che stai confrontando i numeri, è possibile utilizzare un arithmetic expression, che consente più semplice la gestione dei parametri e confronto:

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

Si noti come, invece di -ne, si può semplicemente utilizzare !=. In un contesto aritmetica, non hanno nemmeno bisogno di anteporre $ ai parametri, vale a dire,

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

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

Inoltre, poiché ((...)) valuta valori diversi da zero a vero, cioè, ha una stato di ritorno di 0 per valori diversi da zero e uno stato restituito di 1 altrimenti, potremmo accorciare a

if (($?)); then 

ma questo potrebbe confondere più persone di quante ne valgano i tasti salvati.

Il costrutto ((...)) è disponibile in Bash, ma non richiesto dallo POSIX shell specification (come possibile estensione, tuttavia).

Detto questo, è meglio evitare $? del tutto a mio avviso, come in Cole's answer e Steven's answer.

+0

Sei sicuro di '((...))'? [** POSIX Programmers Reference - Compound Commands **] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04) –

+0

@ DavidC.Rankin Oh, non l'ho trovato! Quindi è menzionato come un'estensione, ma non è richiesto. Correggerò –

+1

Sì, quello mi ha sempre preso anche io. Di certo rende la vita più semplice in shell sebbene ':)' –