Jai un script bash qui définit -e donc le script se terminera à nimporte quel état de sortie! = 0 .
Jessaye de faire de larithmétique basique du shell assignée aux variables et parfois lexpression est égale à 0, ce qui fait que le statut de sortie de la commande let ou expr est « 1 ».
Voici un exemple:
#!/bin/bash -ex echo "Test 1" Z=`expr 1 - 1` || true echo "Z will print" let "A=4 - 4" echo "A WILL NEVER PRINT $A" Y=`expr 1 - 1` echo "Y WILL NEVER PRINT $Y" X=$(expr 2 - 2) echo "X WILL NEVER PRINT $X"
Le résultat est:
$ ./test_error.sh + echo "Test 1" Test 1 ++ expr 1 - 1 + Z=0 + true + echo "Z will print" Z will print + let "A=4 - 4"
Mon La question est de savoir quelle est la manière idiomatique de script bash pour permettre au script déchouer sur des erreurs de sortie réelles et non sur des erreurs arithmétiques de base égalant 0. Je pourrais suffixer toutes ces expressions avec:
A=`expr $C - $D` || true
Mais cela semble piraté.
Réponse
Nutilisez pas expr
pour larithmétique. Elle est obsolète depuis longtemps: les shells ont maintenant larithmétique intégrée, avec la construction $((…))
(POSIX), ou avec let
builtin (ksh / bash / zsh) ou la construction ((…))
(ksh / bash / zsh).
let
et ((…))
renvoie 1 (un code détat déchec) si la dernière expression évaluée est 0. Pour éviter que cela ne provoque la fermeture de votre script sous set -e
, organisez le dernière expression à ne pas renvoyer 0, par exemple:
let "a = 2 - 2" 1 ((a = 2 - 2, 1))
Vous pouvez également utiliser lidiome || true
:
((a = 2 - 2)) || true
Sinon, faites votre calcul à lintérieur de $((…))
et vos devoirs à lextérieur. Une affectation renvoie le statut de la dernière substitution de commande dans la valeur, ou 0 sil ny a pas de substitution de commande, vous êtes donc en sécurité. Cela présente lavantage supplémentaire de travailler dans nimporte quel shell POSIX (comme le tiret).
a=$((2 - 2))
Réponse
Javais le même problème . tl; dr:
Si le dernier ARG [de let] est évalué à 0, let renvoie 1; let renvoie 0 sinon .
Réponse
Utilisez $(( $C - $D ))
à la place pour votre calcul. Cest plus efficace aussi.
Commentaires
Réponse
Cette syntaxe fonctionne pour moi:
a=$((b + c))
(( A = $C - $D ))
?