Il semble qu'il y ait un malentendu à propos de l'utilitaire Bash true
et, plus précisément, sur la façon dont Bash développe et interprète les expressions entre parenthèses.
Le code dans La réponse de miku n'a absolument rien à voir avec l'utilitaire Bash true
ni /bin/true
ni aucune autre saveur de la true
commande. Dans ce cas, true
n'est rien d'autre qu'une simple chaîne de caractères, et aucun appel à la fonction true
n'est jamais faite, ni par l'affectation de variable, ni par l'évaluation de l'expression conditionnelle.
Le code suivant est fonctionnellement identique au code de la réponse du miku :
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
Le site uniquement La différence ici est que les quatre caractères comparés sont " y ", " e ", " a " et " h " au lieu de " t ", " r ", " u " et " e ". Et c'est tout. Il n'y a aucune tentative d'appeler une commande ou un module intégré nommé yeah
et il n'y a pas non plus (dans l'exemple de miku) de traitement spécial lorsque Bash analyse le jeton true
. C'est juste une chaîne, et une chaîne complètement arbitraire.
Mise à jour (2014-02-19) : Après avoir suivi le lien dans la réponse de miku, je vois maintenant d'où vient une partie de la confusion. La réponse de Miku utilise des parenthèses simples, mais l'extrait de code vers lequel il renvoie n'utilise pas de parenthèses. C'est juste :
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Les deux extraits de code se comporter de la même façon, mais les supports changent complètement ce qui se passe sous le capot.
Voici ce que fait Bash dans chaque cas :
Pas d'équerres :
- Développez la variable
$the_world_is_flat
à la chaîne de caractères "true"
.
- Tenter d'analyser la chaîne de caractères
"true"
comme une commande.
- Trouvez et exécutez le
true
(soit une commande intégrée ou /bin/true
selon la version de Bash).
- Comparez le code de sortie de la
true
(qui est toujours 0) avec 0. Rappelez-vous que dans la plupart des shells, un code de sortie de 0 indique un succès et tout autre code indique un échec.
- Puisque le code de sortie était 0 (succès), exécutez la commande
if
de la déclaration then
clause
Supports :
- Développez la variable
$the_world_is_flat
à la chaîne de caractères "true"
.
- Analyser l'expression conditionnelle maintenant complètement développée, qui est de la forme
string1 = string2
. Le site =
est l'opérateur de bash comparaison de chaînes opérateur. Alors...
- Faire une comparaison de chaîne sur
"true"
et "true"
.
- Oui, les deux chaînes étaient les mêmes, donc la valeur de la conditionnelle est vraie.
- Exécuter le
if
de la déclaration then
clause.
Le code sans parenthèses fonctionne, parce que l'option true
renvoie un code de sortie de 0, ce qui indique un succès. Le code entre parenthèses fonctionne, car la valeur de $the_world_is_flat
est identique à la chaîne littérale true
sur le côté droit de la =
.
Pour illustrer ce point, considérons les deux extraits de code suivants :
Ce code (s'il est exécuté avec les privilèges de Root) redémarrera votre ordinateur :
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Ce code imprime juste "Bien essayé". La commande reboot n'est pas appelée.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Mise à jour (2014-04-14) Pour répondre à la question dans les commentaires concernant la différence entre =
et ==
: AFAIK, il n'y a pas de différence. Le site ==
est un synonyme spécifique à Bash de =
et, d'après ce que j'ai vu, ils fonctionnent exactement de la même manière dans tous les contextes.
Notez, cependant, que je parle spécifiquement de la =
et ==
les opérateurs de comparaison de chaînes de caractères utilisés dans l'un ou l'autre [ ]
ou [[ ]]
des tests. Je ne suggère pas que =
et ==
sont interchangeables partout dans bash.
Par exemple, il est évident que vous ne pouvez pas faire d'assignation de variable avec ==
tels que var=="foo"
(enfin, techniquement, vous peut le faire, mais la valeur de var
sera "=foo"
parce que Bash ne voit pas de ==
opérateur ici, il voit un =
(affectation), suivi de la valeur littérale ="foo"
qui devient juste "=foo"
).
En outre, bien que =
et ==
sont interchangeables, vous devez garder à l'esprit que la manière dont ces tests fonctionnent fait dépendent du fait que vous l'utilisiez à l'intérieur [ ]
ou [[ ]]
et aussi sur le fait que les opérandes sont ou non cités. Vous pouvez en savoir plus à ce sujet dans Guide avancé du script Bash : 7.3 Autres opérateurs de comparaison (faites défiler vers le bas jusqu'à la discussion sur =
et ==
).