Je sais qu'il y a des valeurs booléennes dans bash
, mais je ne les vois jamais utilisées nulle part.
Je veux écrire un wrapper pour certaines informations souvent recherchées sur ma machine, par exemple, ce lecteur USB particulier est-il inséré / monté.
Quelle serait la meilleure pratique pour y parvenir?
Un string?
drive_xyz_available=true
Un nombre (0 pour vrai, ≠ 0 pour faux)?
drive_xyz_available=0 # evaluates to true
Une fonction?
drive_xyz_available() { if available_magic; then return 0 else return 1 fi }
Je me demande surtout ce à quoi s'attendraient d'autres personnes qui voudraient utiliser le wrapper. S'attendraient-ils à une valeur booléenne, une commande comme une variable ou une fonction à appeler?
Du point de vue de la sécurité, je pense que la deuxième option est la plus sûre, mais j'aimerais entendre vos expériences.
shell
shell-script
Minix
la source
la source
help true ; help false ; help exit
Réponses:
Définissez simplement une variable sur n'importe quoi, mais pas sur null pour que ce qui précède fonctionne, mais
[ -n "$var" ]
serait plus court, sinon aussi évident.En général, lorsqu'un script interprète une variable d'environnement comme vraie ou fausse, il interprète n'importe quelle valeur comme vraie (et utilise parfois cette valeur pour configurer une option) ou bien une valeur nulle comme fausse.
Ce qui précède renvoie la
!not
valeur booléenne du len de son premier argument - si l'argument contient un nombre de caractères différent de 0, il renvoie 0, sinon, s'il n'y a pas de caractères du tout, il renvoie 1. C'est le même test que vous pouvez effectuer avec[ -n "$var" ]
, en gros , mais il l'enveloppe simplement dans une petite fonction nomméebool()
.C'est généralement ainsi que fonctionne une variable indicateur . Par exemple:
Là où d'autres parties d'un script n'ont besoin que de rechercher une valeur
$dir
pour évaluer son utilité. Cela est également utile en ce qui concerne la substitution de paramètres - car les paramètres peuvent être étendus aux valeurs par défaut pour être remplacés par des paramètres vides ou non définis, mais se développeront autrement à une valeur prédéfinie comme ...... qui imprimerait ...
Bien sûr, il est également possible de faire le contraire avec
:+
mais cela ne peut que vous donner un défaut prédéfini ou rien du tout, tandis que le formulaire ci-dessus peut vous donner une valeur ou une valeur par défaut.Et donc en ce qui concerne les trois choix - chacun pourrait fonctionner selon la façon dont vous choisissez de le mettre en œuvre. Le retour de la fonction est auto-test, mais, si ce retour doit être sauvegardé pour une raison quelconque, il devra être mis dans une variable. Cela dépend du cas d'utilisation - la valeur booléenne que vous souhaitez évaluer un test une fois et est-elle de type? Si c'est le cas, faites la fonction, sinon l'un des deux autres est probablement nécessaire.
la source
true
false
if $variable; then ...
$IFS
- et si la valeur de la var peut contenir des entrées utilisateur de toute nature, alors aussi bonne chance. Si la valeur n'est pas inconnue au départ, il n'est pas nécessaire de la tester. Vous pouvez le faire en toute sécuritéif ${var:+":"} false; then
lorsque vous travaillez avec des valeurs booléennes null / not null. Mais c'est rarement plus utile que[ -n "$var" ] &&
variable=false
puis le définit sur true en fonction de la condition (comme je le ferais lors de l'utilisation d'une variable en C), il n'y a aucun problème, quelle est votre obsession de faire varier les valeurs IFS et les valeurs de variables aléatoires, etc. de toute façon .. .Dans
bash
chaque variable se trouve essentiellement une chaîne (ou un tableau ou une fonction, mais parlons ici des variables régulières).Les conditions sont analysées en fonction des valeurs de retour des commandes de test - la valeur de retour n'est pas une variable, c'est un état de sortie. Lorsque vous évaluez
if [ ... ]
ouif [[ ]]
ouif grep something
ou quelque chose comme ça, la valeur de retour 0 (pas la chaîne 0, mais l'état de sortie 0 = succès) signifie vrai et le reste signifie faux (donc, exactement le contraire de ce à quoi vous êtes habitué dans les langages de programmation compilés, mais comme il existe un moyen de réussir et de nombreuses façons d'échouer, et que le résultat attendu de l'exécution est généralement un succès, 0 est utilisé comme résultat par défaut le plus courant si rien ne va mal). C'est très utile car tout binaire peut être utilisé comme test - s'il échoue, c'est faux, sinon c'est vrai.true
et lesfalse
programmes (généralement remplacés par les prédéfinis) ne sont que de petits programmes utiles qui ne font rien -true
réussissent à ne rien faire et se terminent par 0, tandis qu'ilsfalse
essaient de ne rien faire et "échouent", se terminant par 1. Cela semble inutile mais c'est très pratique pour l'écriture de scripts.Quant à savoir comment transmettre la vérité, c'est à vous de décider. Il est assez courant d'utiliser simplement "y" ou "oui" pour la vérité et l'utilisation
if [ x"$variable" = x"yes" ]
(en ajoutant la chaîne facticex
parce que s'il$variable
se trouve être de longueur nulle, cela protège de la création d'une fausse commandeif [ = "yes" ]
qui n'analyse pas). Il peut également être utile d'utiliser simplement une chaîne vide pour false et[ -z "$variable ]
de tester si sa longueur est nulle (ou-n
pour qu'elle soit différente de zéro).Quoi qu'il en soit, il est assez rare de devoir passer des valeurs booléennes dans
bash
- il est beaucoup plus courant de simplementexit
en cas d'échec, ou de retourner un résultat utile (ou zéro en cas de problème et de tester une chaîne vide), et la plupart des cas peuvent tester l'échec directement à partir du statut de sortie.Dans votre cas, vous voulez une fonction qui agira comme n'importe quelle autre commande (par conséquent, retourne 0 en cas de succès), donc votre dernière option semble le bon choix.
De plus, vous n'aurez peut-être même pas besoin de
return
déclaration. Si la fonction est assez simple, vous pouvez utiliser le fait qu'elle renvoie simplement l'état de la dernière commande exécutée dans la fonction. Ainsi, votre fonction peut simplement êtresi vous testez l'existence d'un nœud de périphérique (ou grep
/proc/mounts
pour vérifier s'il est monté?).la source
drive_xyz_available()
est la plus courante?y = true
cas commun ? D'après mon expérience, la plupart des scripts wrapper testent toute valeur non nulle pour la considérer comme vraie - du moins en ce qui concerne les variables d'environnement interprétées. Sinon, ils ignorent complètement les voitures obus.if
test n'est pas nécessaire si la variable est citée;if [ "$variable" = "yes" ]
fonctionne bien même si $ variable n'est pas défini.Fondamentalement, tout nombre différent de 0 est vrai et 0 est faux. Raison du retour des valeurs à 0 pour une fin réussie d'un script ou de tout autre nombre afin d'identifier différents types d'erreurs.
$?
renverra le code de sortie de la commande / exécutable précédente, soit 0 succès et tout autre numéro l'erreur qui a été renvoyée.J'utiliserais donc cette méthode pour vrai / faux.
if (( ! $? ));then OK;else NOOK;fi
la source
true; echo $?
etfalse; echo $?
.!
le résultat pour qu'il soit VRAI. Le résultat d'une commande est 0 lorsqu'elle s'est terminée correctement, ce qui ne signifie pas que 0 est vrai. Le mottrue
peut être 0, mais 0 n'est jamais vrai comme leif
montre la condition.0
revient à dire qu'en C / C ++, c'esttrue
parce queif(!x){True();}else{False();}
va appelerTrue()
quandx==0
. Mais la vérification correcte ne serait pas!x
, mais plutôt!!x
.if
je déclare simplement le fait qu'ici (en bash, ou ksh, ou tsh, ou ....) comme en C / C ++ un 0 est FAUX, tout un autre nombre est VRAI, comme vous pouvez le lire dans le lien qui suit, les implémentations initiales de C n'ont fourni aucun type booléen, étant définies comme des entiers où 0 était FAUX et 1 VRAI en.wikipedia.org/wiki/Boolean_data_type .