Negar si la condición en script bash


163

Soy nuevo en bash y estoy atascado al tratar de negar el siguiente comando:

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

Esto si la condición devuelve verdadero si estoy conectado a internet. Quiero que suceda al revés, pero poner en !cualquier lugar no parece funcionar.


3
¿Donde lo pusiste? if ! [[ ...funciona
ese otro tipo

1
También puede usarlo de esta manera: wget your_xxxx_params || (echo "oh oh" && salida 1)
AKS

2
> llamar a una subshell solo para generar un error
tijagi

Respuestas:


227

Tu puedes elegir:

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

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

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

! invierte el retorno de la siguiente expresión, respectivamente.


9
¿son necesarios los corchetes dobles? ¿porqué es eso?
Alexander Mills

1
@AlexanderMills: Hay varias formas de hacer esto. Con corchetes dobles o simples o con testcomando:if test $? -ne 0; then
Cyrus

44
Esta respuesta es innecesariamente detallada. ifespera una declaración que sea 0 o 1, por lo que puede usar el comando en sí mismo e invertirlo:if ! wget ...; then ...; fi
Nils Magnus


8

Si se siente flojo, aquí hay un método conciso para manejar las condiciones usando ||(o) y &&(y) después de la operación:

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

8
En los scripts de la vida real, debe cambiar el &&comando after the echo a a ;. La razón de esto es que si la salida se redirige a un archivo en un disco lleno, echodevolverá el error y exitnunca se disparará. Probablemente este no sea el comportamiento que desea.
Score_Under

o puede usar set -ey fallar echosaldrá del script de todos modos
Jakub Bochenski

4

Como está comparando números, puede usar una expresión aritmética , que permite un manejo más simple de los parámetros y la comparación:

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

Observe cómo en lugar de -ne, simplemente puede usar !=. En un contexto aritmético, ni siquiera tenemos que anteponer los $parámetros, es decir,

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

Funciona perfectamente bien. Sin embargo, esto no se aplica al $?parámetro especial.

Además, dado que (( ... ))evalúa los valores distintos de cero a verdadero, es decir, tiene un estado de retorno de 0 para valores distintos de cero y un estado de retorno de 1 de lo contrario, podríamos acortarlo a

if (( $? )); then

pero esto podría confundir a más personas de lo que valen las pulsaciones de teclas guardadas.

La (( ... ))construcción está disponible en Bash, pero no es requerida por la especificación de shell POSIX (aunque mencionada como posible extensión).

Todo esto se dice, es mejor evitar $?por completo en mi opinión, al igual que en la respuesta de Cole y la respuesta de Steven .



@ DavidC.Rankin ¡Oh, no encontré eso! Por lo tanto, se menciona como una extensión, pero no es obligatorio. Lo enmendaré.
Benjamin W.

1
Sí, ese siempre me tiene a mí también. Sin embargo:)
David C. Rankin el

4

Puede usar una comparación desigual en -nelugar de -eq:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.