Une approche consiste à utiliser une expression régulière, comme ceci :
re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
echo "error: Not a number" >&2; exit 1
fi
Si la valeur n'est pas nécessairement un entier, envisagez de modifier l'expression régulière de manière appropriée ; par exemple :
^[0-9]+([.][0-9]+)?$
...ou, pour manipuler les nombres avec un signe :
^[+-]?[0-9]+([.][0-9]+)?$
Personne n'a suggéré le pattern matching étendu de bash :
[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"
ou en utilisant une classe de caractères POSIX :
[[ $1 == ?(-)+([[:digit:]]) ]] && echo "$1 is an integer"
La solution suivante peut également être utilisée dans des shells de base tels que Bourne sans avoir besoin d'expressions régulières. Fondamentalement, toute opération d'évaluation de valeur numérique utilisant des non-nombres entraînera une erreur qui sera implicitement considérée comme fausse dans le shell :
"$var" -eq "$var"
comme dans :
#!/bin/bash
var=a
if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
echo number
else
echo not a number
fi
Vous pouvez également tester pour $ ? le code retour de l'opération qui est plus explicite :
[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
echo $var is not number
fi
La redirection de l'erreur standard est là pour masquer le message "expression entière attendue" que bash affiche au cas où nous n'aurions pas de nombre.
MISE EN GARDE (merci aux commentaires ci-dessous):
- Les nombres avec des points décimaux ne sont pas identifiés comme des "numéros" valides
- Utiliser
[[ ]]
au lieu de[ ]
sera toujours évalué àtrue
- La plupart des shells non-Bash évalueront toujours cette expression comme
true
- Le comportement dans Bash n'est pas documenté et peut donc changer sans avertissement
- Si la valeur comprend des espaces après le nombre (par exemple "1 a") produit une erreur, comme
bash: [[: 1 a: syntax error in expression (error token is "a")
- Si la valeur est la même que var-name (par exemple, i="i"), produit une erreur, comme
bash: [[: i: expression recursion level exceeded (error token is "i")
Sans bashismes (fonctionne même dans le System V sh),
case $string in
''|*[!0-9]*) echo bad ;;
*) echo good ;;
esac
Cela rejette les chaînes vides et les chaînes contenant des non-chiffres, acceptant tout le reste.
Les nombres négatifs ou à virgule flottante nécessitent un travail supplémentaire. Une idée est d'exclure -
/ .
dans le premier "mauvais" modèle et ajouter d'autres "mauvais" modèles contenant leurs utilisations inappropriées (?*-*
/ *.*.*
)