Il semble y avoir un malentendu ici à propos de la fonction intégrée de Bash true
, et plus précisément de la façon dont Bash développe et interprète les expressions entre crochets.
Le code dans la réponse de miku n'a absolument rien à voir avec le Bash intégré true
, ni /bin/true
, ni aucune autre saveur de la true
commande. Dans ce cas, true
n'est rien de plus qu'une simple chaîne de caractères, et aucun appel à la true
commande / builtin n'est jamais effectué, ni par l'affectation de variable, ni par l'évaluation de l'expression conditionnelle.
Le code suivant est fonctionnellement identique au code dans 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
La seule 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». C'est ça. Il n'y a aucune tentative d'appeler une commande ou une commande intégrée nommée yeah
, ni (dans l'exemple de miku) aucune sorte de traitement spécial en cours lorsque Bash analyse le jeton true
. C'est juste une chaîne, et complètement arbitraire.
Mise à jour (2014-02-19): Après avoir suivi le lien dans la réponse de miku, maintenant je vois d'où vient une partie de la confusion. La réponse de Miku utilise des crochets simples, mais l'extrait de code auquel il renvoie n'utilise pas de crochets. 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 comporteront de la même manière, mais les crochets changent complètement ce qui se passe sous le capot.
Voici ce que Bash fait dans chaque cas:
Pas de parenthèses:
- Développez la variable
$the_world_is_flat
dans la chaîne "true"
.
- Essayez d'analyser la chaîne en
"true"
tant que commande.
- Recherchez et exécutez la
true
commande (soit intégrée, soit /bin/true
, selon la version de Bash).
- Comparez le code de sortie de la
true
commande (qui est toujours 0) avec 0. Rappelez-vous que dans la plupart des shells, un code de sortie de 0 indique le succès et tout le reste indique l'échec.
- Puisque le code de sortie était 0 (succès), exécutez la clause de l'
if
instructionthen
Supports:
- Développez la variable
$the_world_is_flat
dans la chaîne "true"
.
- Analyser l'expression conditionnelle désormais entièrement développée, qui est de la forme
string1 = string2
. L' =
opérateur est l' opérateur de comparaison de chaînes de bash . Donc...
- Faites une comparaison de chaînes sur
"true"
et "true"
.
- Oui, les deux chaînes étaient les mêmes, donc la valeur du conditionnel est vraie.
- Exécutez la clause de l'
if
instruction then
.
Le code sans parenthèses fonctionne, car la true
commande renvoie un code de sortie de 0, ce qui indique la réussite. Le code entre crochets fonctionne, car la valeur de $the_world_is_flat
est identique à la chaîne littérale true
sur le côté droit de la =
.
Juste pour enfoncer le clou, considérez les deux extraits de code suivants:
Ce code (s'il est exécuté avec les privilèges root) redémarrera votre ordinateur:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Ce code affiche simplement "Nice try." La commande de redémarrage 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. L' ==
opérateur est un synonyme spécifique à Bash =
et, pour autant que je sache, ils fonctionnent exactement de la même manière dans tous les contextes.
Notez, cependant, que je parle spécifiquement des opérateurs de comparaison de chaînes =
et ==
utilisés dans l'un [ ]
ou dans les [[ ]]
tests. Je ne suggère pas cela =
et ==
sont interchangeables partout dans bash.
Par exemple, vous ne pouvez évidemment pas faire d'affectation de variable avec ==
, comme var=="foo"
(eh bien techniquement, vous pouvez le faire, mais la valeur de var
sera "=foo"
, parce que Bash ne voit pas d' ==
opérateur ici, il voit un =
opérateur (d'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 ces travaux de la façon dont les tests ne dépendent que vous utilisez à l'intérieur [ ]
ou [[ ]]
, et aussi si les opérandes sont cités ou non. Vous pouvez en savoir plus à ce sujet dans Advanced Bash Scripting Guide: 7.3 Autres opérateurs de comparaison (faites défiler jusqu'à la discussion sur =
et ==
).
true
etfalse
dans le contexte de la plupart des extraits ci-dessous, ce ne sont que des chaînes simples, pas lebash built-ins
!!! Veuillez lire la réponse de Mike Holt ci-dessous. (Ceci est un exemple où une réponse fortement votée et acceptée est à