La syntaxe du shell dépend fortement du contexte. Autrement dit, qu'est-ce qu'une chose particulière (comme true
ou false
) signifie dépend beaucoup de l'endroit où il se produit. Dans vos exemples, false
a trois significations complètement différentes :une commande, une valeur de chaîne et un nom de variable (inexistant) contenant une valeur entière. Permettez-moi de passer en revue les exemples :
-
false
sous forme de commande :false; echo $? # prints "1" if false; then echo "yep"; else echo "nope"; fi # prints "nope"
Il existe une commande nommée "false" (généralement /usr/bin/false, ou une commande interne bash qui fait la même chose) qui ne fait rien d'autre que de quitter avec un statut d'échec. En tant que statut de sortie, zéro indique le succès (ce qui ressemble à la vérité) et différent de zéro indique l'échec (ce qui ressemble à un faux). C'est l'opposé de la convention plus habituelle zéro=faux, différent de zéro=vrai, mais pour les statuts de sortie, cela a plus de sens.
-
false
en tant que valeur de chaîne non interprétée :if [[ false ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ true ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ wibble ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ "this is a string" ]]; then echo "yep"; else echo "nope"; fi # prints "yep" [[ false ]]; echo $? # prints "0" (=success) [ false ]; echo $? # prints "0" (=success) test false; echo $? # prints "0" (=success)
Dans tous ces cas, la commande
test
ou son synonyme[
ou l'expression conditionnelle bash[[ ]]
n'ont pas obtenu d'expression, juste une seule chaîne, ils effectuent donc un test très simple :est-ce une chaîne de longueur non nulle ? "true", "false", "wibble", etc. sont tous de longueur non nulle, donc la commande/expression est semblable à la vérité, donc réussie. Comparez avec :[[ "" ]]; echo $? # prints "1" (=failure), because the string is zero-length [[ ]]; echo $? # prints "1" (=failure), because there isn't even a string [ ]; echo $? # same
Notez que
test
et[
sont des commandes normales, et "false" (et "wibble", etc.) n'est qu'un argument.[[ ]]
est un peu de syntaxe bash qui peut être utilisée à la place d'une commande. Leurs arguments/contenus sont analysés différemment des noms de commande eux-mêmes. -
false
comme nom de variable possible pouvant contenir un entier :if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # prints "equal"
Celui-ci est un peu plus étrange et dépend des détails de la façon dont bash est
[[ ]]
teste l'égalité numérique. Notez qu'en[[ ]]
(et[ ]
ettest
expressions),-eq
teste l'égalité numérique, et=
teste l'égalité des chaînes. Ainsi, par exemple,[[ 01 -eq 1 ]]
(car 1 et 01 sont numériquement égaux) est vrai, mais[[ 01 = 1 ]]
est faux (car il ne s'agit pas de la même chaîne). Dans le cas de[[ false -eq true ]]
, "true" et "false" ne sont pas des valeurs entières, donc bash essaie de les convertir en entiers en les traitant comme des noms de variables (et en espérant que les variables contiennent des valeurs entières). En fait, ni l'un ni l'autre n'est défini comme une variable, donc ils évaluent tous les deux la chaîne vide, qui peut en quelque sorte être interprétée comme l'entier 0. Observe :if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # prints "equal" if [[ false -eq 0 ]]; then echo "equal"; else echo "nope"; fi # prints "equal" false=5 if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # now prints "nope"
Notez que la définition de
false
en tant que variable n'a aucun effet sur ses autres utilisations ; lorsqu'il est utilisé en tant que commande, il se terminera toujours avec le statut 1, et lorsqu'il est utilisé en tant que chaîne, il est toujours juste "faux" (pas "5").