L’interpréteur bash embarque un mode arithmétique très pratique pour des calculs sur des entiers.
Par exemple pour tester si une chaîne est de la forme aaa.bbb.ccc.ddd où les aaa, … ddd sont des entiers entre 0 et 255 (adresse IPv4) on peut être tenter d’extraire ce qui est séparé par des ‘.’ et de tester que l’on ne dépasse pas 255.
`
#!/bin/bash
set -euo pipefail
# shopt -o -s nounset
# validation function one parameter “$IP” required
function isIPv4()
{
(( $# == 1 )) || return 1
declare v="" # v without numeric/integer attribute
declare -a values
IFS=’.’ read -a values <<< "$1"
declare -i nvals=${#values[@]}
(( nvals == 4 )) || return 1
declare -i vn=9
declare -p values v vn &>>$FLOG
for v in "${values[@]}"
do
# declare vn="$v" || return 1 # si -i et v="ttt" unbound variable (avec set -u)
set +u
vn="${v:-}"
set -u
(( vn >= 0 )) || return 1
(( vn <= 255 )) || return 1
# a value of "xxx" gives 0 in numeric context automatically
if (( vn == 0 )); then
# [[ "$v" ]] || return 1
[[ "W${v}" == "W0" ]] || return 1
fi
done
return 0
}
# validation function one parameter “$IP” required
isIP()
{
(( $# == 1 )) || return 1
declare v="" # v without numeric/integer attribute
declare -a values # =( “placeholder” )
IFS='.' read -a values <<< "$1"
set – “${values[@]:+}” break $good
set -- "${values[@]:-}"
(( $# == 4 )) || return 1
for v
do
set +u
declare -i vn="${v}"
set -u
(( vn >= 0 )) || return 1
(( vn <= 255 )) || return 1
# a value of "xxx" gives 0 in numeric context automatically
if (( vn == 0 )); then
# [[ "$v" ]] || return 1
[[ "W${v}" == "W0" ]] || return 1
fi
done
return 0
}
# run the given preducate :
function vraifaux() {
"$@" && echo ‘vrai’ || echo “faux”
}
test_IPs() {
declare IP res res2
printf " IP\t\t\tresult\tres2\n"
for IP
do
res=$(vraifaux isIPv4 “$IP”)
res2=$(vraifaux isIP “$IP”)
printf “”%s"\t\t%s\t%s\n" “$IP” “$res” "$res2"
done
}
do_tests() {
declare vide="" space=" " good="10.67.24.198"
test_IPs “$good” “10.67.24.0” "10.67.24"
echo
# set -x
QQQ="sss"
test_IPs “$good” “$vide” “$space” “10.67.24.QQQ”
}
(( $# == 0 )) && do_tests || test_IPs “$@”
`
Le nouveau widget d’édition est une vraie catastrophe
Lançcons notre test intégré
`
fp2x@drhpcmsa:/tmp$ ./test_IP.sh
IP result res2
"10.67.24.198" vrai vrai
"10.67.24.0" vrai vrai
"10.67.24" faux faux
IP result res2
"10.67.24.198" vrai vrai
"" faux faux
" " faux faux
"10.67.24.QQQ" faux faux
`
On pourrait se dire que c’est gagné! Un lecteur attentif aura remarqué les bidouilles set +u/set -u
En fait nous n’avons que repoussé le problème.
fp2x@drhpcmsa:/tmp$ AA="BB" BB="CC" CC="DD" DD="10" ./test_IP.sh 10.10.10.10 AA. BB.CC.DD IP result res2 "10.10.10.10" vrai vrai "AA.BB.CC.DD" vrai vrai
La chaîne “AA.BB.CC.DD” est évaluée comme “10.10.10.10” et passe le test!
D’ailleurs ces fonctions sont loin d’être robustes
fp2x@drhpcmsa:/tmp$ AA="BB" BB="CC" CC="DD" DD="AA" ./test_IP.sh 10.10.10.10 AA.BB.CC.DD IP result res2 "10.10.10.10" vrai vrai ./test_IP.sh: ligne 21: DD : dépassement du niveau de récursivité dans l'expression (le symbole erroné est "DD")
On peut rendre isIP plus robuste mais cela demande d’utiliser d’autres techniques comme par exemple les expressions rationnelles et cela est laissé comme exercice au lecteur
Cordialement,
Regards,
Mit freundlichen Grüßen,
مع تحياتي الخالصة
F. Petitjean
Bureau Veritas