J'ai essayé de vérifier si le PHONE_TYPE
la variable contient l'une des trois valeurs valides.
if [ "$PHONE_TYPE" != "NORTEL" ] || [ "$PHONE_TYPE" != "NEC" ] ||
[ "$PHONE_TYPE" != "Cisco" ]
then
echo "Phone type must be nortel,Cisco or nec"
exit
fi
Le code ci-dessus ne fonctionnait pas pour moi, j'ai donc essayé ceci à la place:
if [ "$PHONE_TYPE" == "NORTEL" ] || [ "$PHONE_TYPE" == "NEC" ] ||
[ "$PHONE_TYPE" == "Cisco" ]
then
: # do nothing
else
echo "Phone type must be nortel,Cisco or nec"
exit
fi
Existe-t-il des moyens plus propres pour ce type de tâche?
Je suppose que vous cherchez:
if [ "$PHONE_TYPE" != "NORTEL" ] && [ "$PHONE_TYPE" != "NEC" ] &&
[ "$PHONE_TYPE" != "Cisco" ]
Les règles de ces équivalents sont appelées lois de De Morgan et dans votre cas signifiaient:
not(A || B || C) => not(A) && not(B) && not (C)
Notez la modification de l'opérateur booléen ou et et.
Alors que vous avez essayé de faire:
not(A || B || C) => not(A) || not(B) || not(C)
Ce qui ne fonctionne évidemment pas.
Un moyen beaucoup plus court serait:
if [[ ! $PHONE_TYPE =~ ^(NORTEL|NEC|Cisco)$ ]]; then
echo "Phone type must be nortel, Cisco or nec."
fi
^
- Pour faire correspondre un début au début de la ligne$
- Pour correspondre à la fin de la ligne=~
- Opérateur de comparaison d'expressions régulières intégré à BashBonnes réponses, et une leçon inestimable;) Je veux seulement compléter avec une note.
Le type de test que l'on choisit d'utiliser dépend fortement du code, de la structure, de l'environnement, etc.
Une alternative pourrait être d'utiliser un commutateur ou une instruction case
comme dans:
case "$PHONE_TYPE" in
"NORTEL"|"NEC"|"Cisco")
echo "OK"
;;
*)
echo "Phone type must be nortel,Cisco or nec"
;;
esac
Comme deuxième note, vous devez être prudent en utilisant des noms de variables en majuscules. Il s'agit d'éviter la collision entre les variables introduites par le système, qui est presque toujours entièrement en majuscules. Donc $phone_type
au lieu de $PHONE_TYPE
.
Bien que celui-ci soit sûr, si vous avez l'habitude d'utiliser tous les majuscules, un jour vous pourriez dire IFS="boo"
et vous êtes dans un monde de souffrance.
Il sera également plus facile de repérer ce qui est quoi.
Pas un devoir mais un considérerait fortement.
C'est aussi probablement un bon candidat pour une fonction. Cela facilite la lecture et la maintenance du code. Par exemple.:
valid_phone_type()
{
case "$1" in
"NORTEL"|"NEC")
return 0;;
*)
echo "Model $1 is not supported"
return 1;;
esac
}
if ! valid_phone_type "$phone_type"; then
echo "Bye."
exit 1
fi
Vous devez utiliser des ET et non des OU.
if [ "$PHONE_TYPE" != "NORTEL" ] && [ "$PHONE_TYPE" != "NEC" ] && [ "$PHONE_TYPE" != "Cisco" ]
then
ou
if [ "$PHONE_TYPE" != "NORTEL" -a "$PHONE_TYPE" != "NEC" -a "$PHONE_TYPE" != "Cisco" ]
then
Pour corriger une réponse ci-dessus (car je ne peux pas encore commenter):
PHONE_TYPE="NORTEL"
if [[ $PHONE_TYPE =~ ^(NORTEL|NEC|Cisco|SPACE TEL)$ ]]; then
echo "Phone type accepted."
else
echo "Error! Phone type must be NORTEL, Cisco or NEC."
fi
Veuillez noter que vous avez besoin d'au moins bash 4 pour cette utilisation de = ~
Cela ne fonctionne pas dans bash 3.
J'ai testé sur MS Windows 7 en utilisant bash 4.3.46 (fonctionne bien) et bash 3.1.17 (ne fonctionnait pas)
Le LHS du = ~ doit être entre guillemets. Ci-dessus, PHONE_TYPE = "SPACE TEL" correspondrait également.
Juste une proposition de variation basée sur la solution @ 0x80:
# define phone brand list
phoneBrandList=" NORTEL NEC Cisco" ## separator is space with an extra space in first place
# test if user given phone is contained in the list
if [[ ${phoneBrandList} =~ (^|[[:space:]])"${userPhoneBrand}"($|[[:space:]]) ]]; then
echo "found it !"
fi
Utilisez [[à la place
if [[ "$PHONE_TYPE" != "NORTEL" ]] || [[ "$PHONE_TYPE" != "NEC" ]] ||
[[ "$PHONE_TYPE" != "Cisco" ]]
then
echo "Phone type must be nortel,Cisco or nec"
exit 1
fi