Ajouter (collecter) les codes de sortie dans bash
Question
Je dois dépendre de quelques exécutions distinctes dans un script et ne pas les regrouper dans une instruction "if" moche. Je voudrais prendre le code de sortie '$?' de chaque exécution et l'ajouter; à la fin, si cette valeur dépasse un seuil, j'aimerais exécuter une commande.
Pseudo-code:
ALLOWEDERROR=5
run_something
RESULT=$?
..other things..
run_something_else
RESULT=$RESULT + $?
if [ $RESULT -gt ALLOWEDERROR ]
then echo "Too many errors"
fi
Problème: même si Internet prétend le contraire, bash refuse de traiter le résultat et $? sous forme d'entier. Quelle est la syntaxe correcte?
Merci.
La solution
Vous voudrez peut-être jeter un coup d'œil à la fonction intégrée trap
pour voir si elle vous serait utile:
help trap
ou
man bash
vous pouvez définir une interruption pour des erreurs comme celle-ci:
#!/bin/bash
AllowedError=5
SomeErrorHandler () {
(( errcount++ )) # or (( errcount += $? ))
if (( errcount > $AllowedError ))
then
echo "Too many errors"
exit $errcount
fi
}
trap SomeErrorHandler ERR
for i in {1..6}
do
false
echo "Reached $i" # "Reached 6" is never printed
done
echo "completed" # this is never printed
Si vous comptez les erreurs (et uniquement s'il s'agit d'erreurs) comme ceci au lieu d'utiliser " $?
", vous n'avez pas à vous soucier des valeurs de retour autres que zéro ou un. Une valeur de retour unique de 127, par exemple, vous propulserait immédiatement au-dessus de votre seuil. Vous pouvez également enregistrer des pièges
pour d'autres signaux en plus de ERR
.
Autres conseils
Une expérience rapide et une infiltration dans les informations de bash indiquent:
declare -i RESULT=$RESULT + $?
puisque vous ajoutez plusieurs fois au résultat, vous pouvez utiliser déclarer au début, comme ceci:
declare -i RESULT=0
true
RESULT+=$?
false
RESULT+=$?
false
RESULT+=$?
echo $RESULT
2
qui a l'air beaucoup plus propre.
declare -i
indique que la variable est un entier.
Sinon, vous pouvez éviter de déclarer et d'utiliser des crochets d'expression arithmétique:
RESULT=$(($RESULT+$?))
Utilisez la construction $ ((...))
.
$ cat st.sh
RESULT=0
true
RESULT=$(($RESULT + $?))
false
RESULT=$(($RESULT + $?))
false
RESULT=$(($RESULT + $?))
echo $RESULT
$ sh st.sh
2
$
Pour savoir comment ajouter des nombres dans Bash, voir également:
help let
Si vous souhaitez utiliser ALLOWEDERROR dans votre script, insérez-le précédé d'un $, par exemple $ ALLOWEDERROR.
Voici quelques façons d'effectuer une addition dans bash ou sh:
RESULT=`expr $RESULT + $?`
RESULT=`dc -e "$RESULT $? + pq"`
Et quelques autres en bash seulement:
RESULT=$((RESULT + $?))
RESULT=`bc <<< "$RESULT + $?"`
Quoi qu'il en soit, le statut de sortie en cas d'erreur n'est pas toujours égal à 1 et sa valeur ne dépend pas du niveau d'erreur. Par conséquent, dans le cas général, il n'est pas très utile de vérifier la somme des statuts par rapport à un seuil.
Comme le mentionne le mouviciel, la collecte de la somme des codes de retour est plutôt absurde. Vous pouvez probablement utiliser un tableau pour accumuler des codes de résultat non nuls et vérifier leur longueur. Voici un exemple de cette approche:
#!/bin/sh
declare RESULT
declare index=0
declare ALLOWED_ERROR=1
function write_result {
if [ $1 -gt 0 ]; then
RESULT[index++]=$1
fi
}
true
write_result $?
false
write_result $?
false
write_result $?
echo ${#RESULT[*]}
if [ ${#RESULT[*]} -gt $ALLOWEDERROR ]
then echo "Too many errors"
fi