Comprendre les opérateurs booléens dans le script bash [duplicate]

Cette question a déjà des réponses ici :

Answer

La variable $phone_missing est une chaîne contenant false. Et une chaîne non vide donne la valeur true. Voir aussi http://www.linuxintro.org/wiki/Babe#empty_strings

Commentaires

  • Ah daccord. Jaurais déclaré cette variable comme booléenne (du moins pas avec le mot de déclaration) mais la console ash ne ma pas permis de '. Je ne veux pas ' comparer des chaînes. Comment procéder correctement?
  • stackoverflow.com/questions/2953646/… , mais attention: ce type EXÉCUTE une variable chaîne, et aussi bien false que true sont des commandes unix.

Answer

Jutilise souvent «vrai» et «faux» car ce sont aussi des commandes qui renvoient simplement respectivement le succès et léchec. Ensuite, vous pouvez faire

if "$phone_missing"; then ... 

Répondre

Voici une façon de faire ceci, tout en conservant les valeurs vrai / faux.

 phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is true." fi  

Les guillemets doubles autour $phone_missing servent à protéger contre le cas où la variable phone_missing nest pas du tout définie. Un autre idiome courant à éviter est [ x$phone_missing != xfalse ], mais les citations me semblent plus naturelles.

Lindice se trouve dans la bash page daide pour test:

 STRING True if string is not empty. ... ! EXPR True if expr is false. 

Donc, en gros, [ $foo ] sera vrai si $foo nest pas vide. Nest pas vrai ou faux, juste non vide. [ ! $foo ] est vrai si $ foo est vide ou indéfini.

Vous pouvez toujours changer votre code pour simplement définir phone_missing sur un non -valeur vide e, qui désignera vrai. Si phone_missing nest pas défini (ou vide – phone_missing=""), il sera faux. Sinon, vous devriez utiliser les opérateurs de test de chaîne (= et !=).

Lautre petit problème est la tâche. Vous lavez en tant que $phone_missing=true, alors quil devrait être phone_missing=true (pas de signe dollar).

Désolé si cest un peu dense, cest parce que je le suis. Ça a été une longue journée. 🙂

Réponse

Dautres réponses vous ont apporté une solution, mais je vais vous expliquer ce qui nallait pas avec la pensée originale.

Les variables Bash nont pas de types, donc il ny a pas de variable booléenne ou de valeur comme true ou false. En gros, toutes les variables bash ne sont que des chaînes.

Lorsque vous testez une variable / chaîne dans bash sans spécifier le type de test (-n ou -z), il sera par défaut un test -n (chaîne de longueur différente de zéro).

Donc [ "$var" ] équivaut à [ -n "$var" ]. Tant que $var contient au moins 1 caractère, il a été évalué comme vrai.

Puisque vous avez annulé lexpression, [ ! "$var" ] équivaut à [ ! -n "$var" ]. Donc, si $var contient au moins 1 caractère, alors lexpression est fausse.

Depuis false (qui est juste une chaîne) contient 5 caractères, lexpression est fausse. Si la chaîne que vous définissez phone_missing sur (true, 0, 1) na pas dimportance, lexpression sera toujours false car is phone_missing a une longueur différente de zéro. Le seul moyen de le rendre true est de phone_missing="" car cest une longueur nulle.

Réponse

Nutilisez pas de chaîne pour le booléen. Utilisez un entier.

Entrée:

val=1 ((val)) && echo "true" || echo "false" val=0 ((val)) && echo "true" || echo "false" 

Sortie:

true false 

Source :

((expression))

Lexpression est évaluée selon les règles décrites ci-dessous sous ÉVALUATION ARITHMÉTIQUE. Si la valeur de lexpression est différente de zéro, létat de retour est 0; sinon, létat de retour est 1. Cest exactement équivalent à let « expression ».

Réponse

Jaurais fait cela comme un commentaire pour soutenir James Ko mais na pas eu le représentant pour commenter ou voter publiquement.

Le problème ici est que les crochets [] sont une notation pour faire un test de comparaison tel que légalité de valeur ou de chaîne.

La véracité de la chaîne en bash pour une chaîne vide est "" (chaîne vide) est évaluée à false (valeur de retour 1) et toute chaîne non vide « false » « true « ou » bob « est votre oncle » évalue à vrai (valeur de retour 0).

Vous pouvez vous le prouver avec:

 if [ "foo" ]; then echo true is $?; else echo false is $?; fi 

Le $? ci-dessus est une variable spéciale qui contient le dernier état de sortie des commandes (0 succès, et tout> 0 pour le code derreur) et affichera true is 0. Vous pouvez remplacer "foo" par tout ce que vous voulez et le résultat sera le même sauf si vous le remplacez par une chaîne vide "" ou "" auquel cas il évaluera la condition else et affichera false is 1.

Lors de lutilisation de [ ] entre crochets linstruction interne telle que! $ phone_missing est évaluée, puis renvoie un 0 pour vrai ou 1 pour faux au contrôle if l déclaration. Puisque le crochet évalue les comparaisons de chaînes et de valeurs, $ phone_missing est dabord étendu à la chaîne non vide « false » qui est évaluée par le [] comme une chaîne non vide (ou true), puis le! inverse le résultat qui aboutit à ce que linstruction if obtienne une valeur false (ou une valeur de retour 1) et ignore le corps conditionnel exécutant linstruction else si elle est présente.

Comme James Ko la dit, la notation serait de simplement passer le variable contenant votre « booléen » à linstruction de contrôle if. Remarque que dans bash un booléen vrai et faux doit être en minuscule comme dans: bool_true = true bool_false = false Tout autre cas sera évaluer comme des chaînes et non des booléens.

Donc, en utilisant votre exemple et la réponse de James Ko, ce serait:

phone_missing=false echo "missing $phone_missing" if ! $phone_missing then echo "Lost phone at $readabletime" $phone_missing=true fi 

ou comme je préférez la lisibilité (syntaxiquement identique à celle de James Ko)

phone_missing=false echo "missing $phone_missing" if ( ! $phone_missing ); then echo "Lost phone at $readabletime" $phone_missing=true fi 

Dautres réponses telles que celles dAlexios vérifient littéralement le contenu de la chaîne. Pour que lun ou lautre des éléments suivants donne un résultat faux:

phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == Bobs_your_uncle ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi 

Réponse

La syntaxe correcte est if ! $bool; then [statements]; fi.

Exemple:

bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi 

Résultat: This is correct!

Commentaires

  • Il y a un noyau de vérité dans votre réponse, mais, faute dexplication, cela cause plus confusion qu’elle remédie. En outre, ce nest guère plus quune répétition de lune des réponses précédentes. Si vous ne souhaitez pas que votre réponse soit supprimée, expliquez pourquoi elle est correcte.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *