Ce que vous avez écrit fonctionne en fait presque (cela fonctionnerait si toutes les variables étaient des nombres), mais ce n'est pas du tout une manière idiomatique.
(…)
les parenthèses indiquent un sous - shell . Ce qui s'y trouve n'est pas une expression comme dans beaucoup d'autres langues. C'est une liste de commandes (tout comme les parenthèses extérieures). Ces commandes sont exécutées dans un sous-processus distinct, donc toute redirection, affectation, etc. effectuée à l'intérieur des parenthèses n'a aucun effet en dehors des parenthèses.
- Avec un signe dollar en tête,
$(…)
est une substitution de commande : il y a une commande à l'intérieur des parenthèses, et la sortie de la commande est utilisée dans le cadre de la ligne de commande (après des extensions supplémentaires, sauf si la substitution se fait entre guillemets doubles, mais c'est une autre histoire ) .
{ … }
les accolades sont comme des parenthèses en ce qu'elles regroupent les commandes, mais elles n'influencent que l'analyse, pas le regroupement. Le programme x=2; { x=4; }; echo $x
imprime 4, tandis que x=2; (x=4); echo $x
imprime 2. (Les accolades nécessitent également des espaces autour d'eux et un point-virgule avant de se fermer, contrairement aux parenthèses. Ce n'est qu'une bizarrerie syntaxique.)
- Avec un signe dollar en tête,
${VAR}
est une expansion de paramètre , augmentant à la valeur d'une variable, avec des transformations supplémentaires possibles.
((…))
des parenthèses doubles entourent une instruction arithmétique , c'est-à-dire un calcul sur des entiers, avec une syntaxe ressemblant à d'autres langages de programmation. Cette syntaxe est principalement utilisée pour les affectations et les conditions.
- La même syntaxe est utilisée dans les expressions arithmétiques
$((…))
, qui s'étendent jusqu'à la valeur entière de l'expression.
[[ … ]]
des crochets doubles entourent les expressions conditionnelles . Les expressions conditionnelles sont principalement basées sur opérateurs tels que -n $variable
pour tester si une variable est vide et -e $file
pour tester si un fichier existe. Il existe également des opérateurs d'égalité de chaîne: "$string1" == "$string2"
(attention, le côté droit est un modèle, par exemple [[ $foo == a* ]]
teste si $foo
commence par a
tandis que [[ $foo == "a*" ]]
teste si $foo
c'est exactement a*
), et le familier !
, &&
et les ||
opérateurs pour la négation, la conjonction et la disjonction ainsi que les parenthèses pour le regroupement. Notez que vous avez besoin d'un espace autour de chaque opérateur (par exemple [[ "$x" == "$y" ]]
, pas [[ "$x"=="$y" ]]
) et d'un espace ou d'un caractère comme à la ;
fois à l'intérieur et à l'extérieur des crochets (par exemple [[ -n $foo ]]
, pas[[-n $foo]]
).
[ … ]
les crochets simples sont une autre forme d'expressions conditionnelles avec plus de bizarreries (mais plus anciennes et plus portables). N'en écrivez pas pour l'instant; commencez à vous en préoccuper lorsque vous trouvez des scripts qui les contiennent.
Voici la façon idiomatique d'écrire votre test en bash:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
Si vous avez besoin de portabilité vers d'autres shells, ce serait le moyen (notez les citations supplémentaires et les jeux de crochets séparés autour de chaque test individuel, et l'utilisation de l' =
opérateur traditionnel plutôt que la ==
variante ksh / bash / zsh ):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
Gilles 'SO- arrête d'être méchant'
la source
==
pour différencier la comparaison de l'attribution d'une variable (ce qui est également le cas=
)[[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]
ne démarrent pas de sous-processus bien que le premier point indique explicitement: "Ce qui est à l'intérieur [parenthèses] n'est pas une expression comme dans beaucoup d'autres langues" - mais il est certainement là! C'est probablement évident pour le wiz bash expérimenté, mais pas même pour moi, immédiatement. La confusion peut survenir car des parenthèses simples peuvent être utilisées dans uneif
instruction, mais pas dans les expressions entre crochets doubles.==
n'est pas vraiment «plus idiomatique» que=
. Ils ont la même signification, mais==
c'est une variante ksh également disponible en bash et zsh, alors qu'elle=
est portable. Il n'y a pas vraiment d'avantage à utiliser==
, et cela ne fonctionne pas en clair.==
intérieur[[ … ]]
, si vous le souhaitez, mais=
a l'avantage de travailler également[ … ]
, donc je vous recommande de ne pas prendre l'habitude d'utiliser==
du tout.très proche
devrait marcher.
le décomposer
est une comparaison entière où comme
est une comparaison de chaînes. sinon, je regroupe juste les comparaisons correctement.
Les crochets doubles délimitent une expression conditionnelle. Et, je trouve ce qui suit être une bonne lecture sur le sujet: "(IBM) Demystify test, [, [[, ((, et si-alors-autre"
la source
't1'
n'est pas nécessaire, non? Parce que contrairement aux instructions arithmétiques entre parenthèses doubles, oùt1
serait une variable,t1
dans une expression conditionnelle entre crochets, il s'agit simplement d'une chaîne littérale. C'est à dire,[[ $varB == 't1' ]]
c'est exactement la même chose[[ $varB == t1 ]]
, non?Une version très portable (même pour le shell bourne hérité):
Cela a la qualité supplémentaire d'exécuter un seul sous-processus au plus (qui est le processus
[
), quelle que soit la saveur du shell.Remplacez
=
par-eq
si les variables contiennent des valeurs numériques, par exemple3 -eq 03
est vrai, mais3 = 03
c'est faux. (comparaison de chaînes)la source
Voici le code de la version courte de l'instruction if-then-else:
Faites attention aux points suivants:
||
et les&&
opérandes à l'intérieur si la condition (c'est-à-dire entre parenthèses rondes) sont des opérandes logiques (ou / et)||
et les&&
opérandes à l'extérieur si la condition signifie alors / sinonEn pratique, la déclaration dit:
si (a = 1 ou b = 2) alors "ok" sinon "nok"
la source
( ... )
crée un sous-shell. Peut vouloir utiliser des accolades à la{ ... }
place. Tout état créé dans un sous-shell ne sera pas visible dans l'appelant.la source