Nier la condition if dans le script bash

163

Je suis nouveau dans bash et je suis bloqué en essayant d'annuler la commande suivante:

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

Cette condition si retourne true si je suis connecté à Internet. Je veux que ça se passe dans l'autre sens, mais mettre !n'importe où ne semble pas fonctionner.

Sudh33ra
la source
3
Où l'avez-vous mis? if ! [[ ...fonctionne
cet autre gars
1
vous pouvez également l'utiliser de cette façon: wget your_xxxx_params || (echo "oh oh" && exit 1)
AKS
2
> appeler un sous-shell juste pour afficher une erreur
tijagi

Réponses:

227

Tu peux choisir:

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

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

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

! inverse respectivement le retour de l'expression suivante.

Cyrus
la source
9
les doubles crochets sont-ils nécessaires? pourquoi donc?
Alexander Mills
1
@AlexanderMills: Il existe plusieurs façons de procéder. Avec crochets doubles ou simples ou avec testcommande:if test $? -ne 0; then
Cyrus
4
Cette réponse est inutile et verbeuse. ifattend une instruction qui vaut 0 ou 1, vous pouvez donc utiliser la commande elle-même et l'inverser:if ! wget ...; then ...; fi
Nils Magnus
87

Mieux

if ! wget -q --spider --tries=10 --timeout=20 google.com
then
  echo 'Sorry you are Offline'
  exit 1
fi
Steven Penny
la source
1
Important: gardez un espace entre la !commande et la commande suivante, sinon vous ferez une expansion de l'historique. unix.stackexchange.com/questions/3747/…
Roland
2
Steven pourquoi n'avez-vous qu'une seule réputation?
Roland le
8

Si vous vous sentez paresseux, voici une méthode laconique de gestion des conditions en utilisant ||(ou) et &&(et) après l'opération:

wget -q --tries=10 --timeout=20 --spider http://google.com || \
{ echo "Sorry you are Offline" && exit 1; }
Cole Tierney
la source
8
Dans les scripts réels, vous devez remplacer la &&commande après l'écho par un fichier ;. La raison en est que si la sortie est redirigée vers un fichier sur un disque plein, le echorenverra un échec et le exitne se déclenchera jamais. Ce n'est probablement pas le comportement que vous souhaitez.
Score_Under le
ou vous pouvez utiliser set -eet à défaut echo, vous quitterez le script de toute façon
Jakub Bochenski
4

Puisque vous comparez des nombres, vous pouvez utiliser une expression arithmétique , qui permet une gestion plus simple des paramètres et des comparaisons:

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

Remarquez comment au lieu de -ne, vous pouvez simplement utiliser !=. Dans un contexte arithmétique, nous n'avons même pas besoin de préfixer $les paramètres, c'est-à-dire

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

fonctionne parfaitement bien. Cela ne s'applique cependant pas au $?paramètre spécial.

De plus, puisque (( ... ))évalue les valeurs non nulles à vrai, c'est-à-dire a un état de retour de 0 pour les valeurs non nulles et un état de retour de 1 sinon, nous pourrions raccourcir à

if (( $? )); then

mais cela peut dérouter plus de personnes que ne valent les frappes enregistrées.

La (( ... ))construction est disponible dans Bash, mais n'est pas requise par la spécification du shell POSIX (mentionnée comme une extension possible, cependant).

Tout cela étant dit, il est préférable d'éviter $?tout à fait à mon avis, comme dans la réponse de Cole et la réponse de Steven .

Benjamin W.
la source
Vous en êtes sûr (( ... ))? Référence des programmeurs POSIX - Commandes composées
David C. Rankin
@ DavidC.Rankin Oh, je n'ai pas trouvé ça! Il est donc mentionné comme une extension, mais pas obligatoire. Je vais modifier.
Benjamin W.
1
Oui, celui-là m'a toujours eu aussi. Cela rend la vie plus facile en coquille:)
David C. Rankin
4

Vous pouvez utiliser une comparaison inégale -neau lieu de -eq:

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