Est-ce que cela inclut si une variable IS SET a une valeur de ""?
Brent
11
Oui, c'est le cas ... "-z" teste une chaîne de longueur nulle.
David Z
91
if [ ! -z "$VAR" ];
Aaron Copley
263
l'inverse de -zis-nif [ -n "$VAR" ];
Felipe Alvarez
19
Les guillemets doubles garantissent que la variable ne soit pas divisée. Un simple $varsur une ligne de commande sera divisé par son espace en une liste de paramètres, alors qu’il "$var"ne restera toujours qu’un seul paramètre. Citer des variables est souvent une bonne pratique et vous évite de vous lancer dans des noms de fichiers contenant des espaces (entre autres). Exemple: après avoir a="x --help"essayé cat $a, cela vous donnera la page d’aide pour cat. Ensuite, essayez cat "$a"- ce sera (généralement) dire cat: x --help: No such file or directory. En bref, citez tôt et citez souvent et vous ne le regretterez presque jamais.
Score_Under
247
Dans Bash, lorsque vous n'êtes pas concerné par la portabilité des shells qui ne le prennent pas en charge, vous devez toujours utiliser la syntaxe à double crochet:
Dans Bash, à l'aide de doubles crochets, les guillemets ne sont pas nécessaires. Vous pouvez simplifier le test pour une variable qui contient une valeur comme suit :
if[[ $variable ]]
Cette syntaxe est compatible avec ksh (au moins ksh93, de toute façon). Il ne fonctionne pas avec les coquilles POSIX ou Bourne plus anciennes telles que sh ou dash.
Voir ma réponse ici et BashFAQ / 031 pour plus d'informations sur les différences entre crochets simples et doubles.
Vous pouvez tester si une variable est spécifiquement non définie (par opposition à une chaîne vide):
if[[-z ${variable+x}]]
où le "x" est arbitraire.
Si vous voulez savoir si une variable est null mais pas non définie:
Cela if [[ $variable ]]a bien fonctionné pour moi et je n’avais même pas besoin de ce set -uqui était requis par l’une des solutions proposées.
Teemu Leisti
3
Je pense que c'est mieux que la réponse acceptée.
Qed
2
Pourquoi recommandez-vous une fonctionnalité non portable alors que cela ne présente aucun avantage?
Alastair Irvine
19
@AlastairIrvine: Je mentionne la portabilité dans la première phrase de ma réponse, le titre de la question et le corps contiennent le mot « Bash » et la question est marqué bash , et la double structure de support offre des avantages évidents à bien des égards. Et je ne recommande pas de mélanger les styles de support pour des raisons de cohérence et de facilité de maintenance. Si vous avez besoin de la portabilité maximale, du plus petit commun dénominateur, utilisez shplutôt Bash. Si vous avez besoin des capacités accrues qu’il offre, utilisez Bash et utilisez-le pleinement.
Dennis Williamson
2
@BrunoBronosky: J'ai annulé l'édition. Il n'y a aucune exigence pour ;à la fin. Le thenpeut être sur la ligne suivante sans un point-virgule.
Dennis Williamson
230
Une variable dans bash (et n'importe quel shell compatible POSIX) peut être dans l'un des trois états suivants:
non fixé
mis à la chaîne vide
défini sur une chaîne non vide
La plupart du temps, il suffit de savoir si une variable est définie sur une chaîne non vide, mais il est parfois important de faire la distinction entre non défini et défini sur la chaîne vide.
Voici des exemples de la façon dont vous pouvez tester les différentes possibilités, et cela fonctionne dans bash ou n’importe quel shell compatible POSIX:
if[-z "${VAR}"];then
echo "VAR is unset or set to the empty string"fiif[-z "${VAR+set}"];then
echo "VAR is unset"fiif[-z "${VAR-unset}"];then
echo "VAR is set to the empty string"fiif[-n "${VAR}"];then
echo "VAR is set to a non-empty string"fiif[-n "${VAR+set}"];then
echo "VAR is set, possibly to the empty string"fiif[-n "${VAR-unset}"];then
echo "VAR is either unset or set to a non-empty string"fi
Voici la même chose mais sous forme de tableau pratique:
La ${VAR+foo}construction se développe en chaîne vide si VARest non défini ou to foosi VARest défini sur n'importe quoi (y compris la chaîne vide).
La ${VAR-foo}construction se développe à la valeur de VARif set (y compris set à la chaîne vide) et fooif non définie. Ceci est utile pour fournir des valeurs par défaut remplaçables par l'utilisateur (par exemple, ${COLOR-red}dit d'utiliser redsi la variable COLORn'a pas été définie sur quelque chose).
La raison pour laquelle il [ x"${VAR}" = x ]est souvent recommandé de vérifier si une variable est non définie ou définie sur une chaîne vide est due au fait que certaines implémentations de la [commande (également connues sous le nom de test) sont erronées. Si VARest défini sur quelque chose comme -n, dans ce cas , certaines implémentations ne fonctionneront pas correctement [ "${VAR}" = "" ]car le premier argument de [est interprété à tort comme un -nopérateur, et non comme une chaîne.
Le test d'une variable définie sur la chaîne vide peut également être effectué à l'aide de [ -z "${VAR-set}" ].
Nwellnhof
@nwellnhof: Merci! J'ai mis à jour ma réponse pour utiliser la syntaxe plus courte.
Richard Hansen
Quelle est la différence entre la première et la dernière construction? Ils correspondent tous les deux à "VAR est soit non défini, soit défini sur une chaîne non vide".
Faheem Mitha
1
@FaheemMitha: Ce n'est pas votre faute - ma réponse était difficile à lire. J'ai ajouté un tableau pour rendre la réponse plus claire, espérons-le.
Richard Hansen
2
Les contrôles non définis ne sont pas fiables. Si l'utilisateur a appelé set -uou set -o nounseten bash, le test entraînera simplement l'erreur "bash: VAR: variable non liée". Voir stackoverflow.com/a/13864829 pour une vérification non définie plus fiable. Mon go-to vérifier si une variable est null ou non définie est [ -z "${VAR:-}" ]. Mon chèque pour savoir si une variable est non vide est [ "${VAR:-}" ].
Kevin Jin
38
-z est le meilleur moyen.
Une autre option que j'ai utilisée est de définir une variable, mais elle peut être remplacée par une autre variable, par exemple
export PORT=${MY_PORT:-5432}
Si la $MY_PORTvariable est vide, la valeur PORTest définie sur 5432, sinon PORT est défini sur la valeur MY_PORT. Notez que la syntaxe inclut les deux points et le tiret.
Voici une alternative que j'ai vue [ -z "$foo" ], mais je ne suis pas sûr de savoir pourquoi les gens utilisent cette méthode, tout le monde le sait?
["x${foo}"="x"]
Quoi qu'il en soit, si vous n'autorisez pas les variables non définies (par set -uou set -o nounset), vous rencontrerez des problèmes avec ces deux méthodes. Il y a une solution simple à ceci:
Il y a un commentaire à propos de l'alternative -zà pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Fondamentalement, ce n'est pas censé être une alternative à -z. Plutôt, il gère les cas où $foopourrait s'étendre à quelque chose commençant par un métacaractère qui serait [ou testserait confus par. Mettre un non-métacaractère arbitraire au début élimine cette possibilité.
James Sneeringer
6
La question demande comment vérifier si une variable est une chaîne vide et les meilleures réponses sont déjà données pour cela.
Mais j'ai atterri ici après une période passée en programmation en php et ce que je cherchais était en fait un test similaire à la fonction vide en php fonctionnant dans un shell bash.
Après avoir lu les réponses, je me suis rendu compte que je ne pensais pas correctement dans bash, mais de toute façon, à ce moment-là, une fonction comme vide dans php aurait été très utile dans mon code bash.
Comme je pense que cela peut arriver à d’autres, j’ai décidé de convertir la fonction php empty en bash
selon le manuel php : une variable est considérée comme vide si elle n'existe pas ou si sa valeur est l'une des suivantes:
"" (une chaîne vide)
0 (0 sous forme d'entier)
0.0 (0 en float)
"0" (0 sous forme de chaîne)
un tableau vide
une variable déclarée, mais sans valeur
Bien sûr, les cas nul et faux ne peuvent pas être convertis en bash, ils sont donc omis.
function empty
{local var="$1"# Return true if:# 1. var is a null string ("" as empty string)# 2. a non set variable is passed# 3. a declared variable or array but without a value is passed# 4. an empty array is passedif test -z "$var"then[[ $( echo "1")]]return# Return true if var is zero (0 as an integer or "0" as a string)elif["$var"==02>/dev/null ]then[[ $( echo "1")]]return# Return true if var is 0.0 (0 as a float)elif["$var"==0.02>/dev/null ]then[[ $( echo "1")]]returnfi[[ $( echo "")]]}
Exemple d'utilisation:
if empty "${var}"then
echo "empty"else
echo "not empty"fi
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
Cela dit, dans une logique bash, les vérifications de zéro dans cette fonction peuvent entraîner des problèmes secondaires, toute personne utilisant cette fonction devrait évaluer ce risque et peut-être décider de supprimer ces vérifications en ne laissant que le premier.
Échouera également dans certains coquillages si foo commence par un tiret puisqu'il est interprété comme une option. Par exemple, sur Solaris, ksh , zsh et bash ne posent aucun problème, sh et / bin / test échoueront
ktf
4
Ceci est vrai exactement quand $ FOO est défini et vide:
Certains coquillages n'acceptent pas le double signe égal.
Dennis Williamson
1
La question portait sur bash. J'utilise bash. Fonctionne bien pour moi. De quoi parlez-vous exactement?
Fedir RYKHTIK
2
Si vous utilisez Bash, vous devez utiliser des crochets doubles. Mon commentaire précédent était une simple déclaration de fait pour ceux qui pourraient lire votre réponse et utiliser un shell différent.
Mes 5 centimes: il existe aussi une syntaxe plus courte que if ...celle-ci:
VALUE="${1?"Usage: $0 value"}"
Cette ligne définira VALEUR si un argument a été fourni et imprimera un message d'erreur précédé du numéro de ligne du script en cas d'erreur (et mettra fin à l'exécution du script).
Vous trouverez un autre exemple dans le guide des abs (recherchez "Exemple 10-7").
Pas une réponse exacte, mais a rencontré cette astuce. Si la chaîne que vous recherchez provient d'une "commande", vous pouvez alors la stocker dans un env. variable et ensuite l'exécuter à chaque fois pour l'instruction if, aucun crochet n'est requis!
Par exemple, cette commande, qui détermine si vous êtes sur debian:
Il s’agit donc d’une manière indirecte (en l’exécutant à chaque fois) de rechercher une chaîne vide (il s’agit de rechercher une réponse d’erreur de la commande, mais il renvoie également une chaîne vide).
Réponses:
Cela retournera true si une variable est non définie ou définie sur la chaîne vide ("").
la source
if [ ! -z "$VAR" ];
-z
is-n
if [ -n "$VAR" ];
$var
sur une ligne de commande sera divisé par son espace en une liste de paramètres, alors qu’il"$var"
ne restera toujours qu’un seul paramètre. Citer des variables est souvent une bonne pratique et vous évite de vous lancer dans des noms de fichiers contenant des espaces (entre autres). Exemple: après avoira="x --help"
essayécat $a
, cela vous donnera la page d’aide pourcat
. Ensuite, essayezcat "$a"
- ce sera (généralement) direcat: x --help: No such file or directory
. En bref, citez tôt et citez souvent et vous ne le regretterez presque jamais.Dans Bash, lorsque vous n'êtes pas concerné par la portabilité des shells qui ne le prennent pas en charge, vous devez toujours utiliser la syntaxe à double crochet:
N'importe lequel des éléments suivants:
Dans Bash, à l'aide de doubles crochets, les guillemets ne sont pas nécessaires. Vous pouvez simplifier le test pour une variable qui contient une valeur comme suit :
Cette syntaxe est compatible avec ksh (au moins ksh93, de toute façon). Il ne fonctionne pas avec les coquilles POSIX ou Bourne plus anciennes telles que sh ou dash.
Voir ma réponse ici et BashFAQ / 031 pour plus d'informations sur les différences entre crochets simples et doubles.
Vous pouvez tester si une variable est spécifiquement non définie (par opposition à une chaîne vide):
où le "x" est arbitraire.
Si vous voulez savoir si une variable est null mais pas non définie:
la source
if [[ $variable ]]
a bien fonctionné pour moi et je n’avais même pas besoin de ceset -u
qui était requis par l’une des solutions proposées.sh
plutôt Bash. Si vous avez besoin des capacités accrues qu’il offre, utilisez Bash et utilisez-le pleinement.;
à la fin. Lethen
peut être sur la ligne suivante sans un point-virgule.Une variable dans bash (et n'importe quel shell compatible POSIX) peut être dans l'un des trois états suivants:
La plupart du temps, il suffit de savoir si une variable est définie sur une chaîne non vide, mais il est parfois important de faire la distinction entre non défini et défini sur la chaîne vide.
Voici des exemples de la façon dont vous pouvez tester les différentes possibilités, et cela fonctionne dans bash ou n’importe quel shell compatible POSIX:
Voici la même chose mais sous forme de tableau pratique:
La
${VAR+foo}
construction se développe en chaîne vide siVAR
est non défini ou tofoo
siVAR
est défini sur n'importe quoi (y compris la chaîne vide).La
${VAR-foo}
construction se développe à la valeur deVAR
if set (y compris set à la chaîne vide) etfoo
if non définie. Ceci est utile pour fournir des valeurs par défaut remplaçables par l'utilisateur (par exemple,${COLOR-red}
dit d'utiliserred
si la variableCOLOR
n'a pas été définie sur quelque chose).La raison pour laquelle il
[ x"${VAR}" = x ]
est souvent recommandé de vérifier si une variable est non définie ou définie sur une chaîne vide est due au fait que certaines implémentations de la[
commande (également connues sous le nom detest
) sont erronées. SiVAR
est défini sur quelque chose comme-n
, dans ce cas , certaines implémentations ne fonctionneront pas correctement[ "${VAR}" = "" ]
car le premier argument de[
est interprété à tort comme un-n
opérateur, et non comme une chaîne.la source
[ -z "${VAR-set}" ]
.set -u
ouset -o nounset
en bash, le test entraînera simplement l'erreur "bash: VAR: variable non liée". Voir stackoverflow.com/a/13864829 pour une vérification non définie plus fiable. Mon go-to vérifier si une variable est null ou non définie est[ -z "${VAR:-}" ]
. Mon chèque pour savoir si une variable est non vide est[ "${VAR:-}" ]
.-z
est le meilleur moyen.Une autre option que j'ai utilisée est de définir une variable, mais elle peut être remplacée par une autre variable, par exemple
Si la
$MY_PORT
variable est vide, la valeurPORT
est définie sur 5432, sinon PORT est défini sur la valeurMY_PORT
. Notez que la syntaxe inclut les deux points et le tiret.la source
set -o nounset
dans certains scripts.Si vous souhaitez distinguer les cas d'état jeu vide ou non défini, regardez l'option -u pour bash:
la source
Voici une alternative que j'ai vue
[ -z "$foo" ]
, mais je ne suis pas sûr de savoir pourquoi les gens utilisent cette méthode, tout le monde le sait?Quoi qu'il en soit, si vous n'autorisez pas les variables non définies (par
set -u
ouset -o nounset
), vous rencontrerez des problèmes avec ces deux méthodes. Il y a une solution simple à ceci:Note: cela laissera votre variable undef.
la source
-z
à pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Fondamentalement, ce n'est pas censé être une alternative à-z
. Plutôt, il gère les cas où$foo
pourrait s'étendre à quelque chose commençant par un métacaractère qui serait[
outest
serait confus par. Mettre un non-métacaractère arbitraire au début élimine cette possibilité.La question demande comment vérifier si une variable est une chaîne vide et les meilleures réponses sont déjà données pour cela.
Mais j'ai atterri ici après une période passée en programmation en php et ce que je cherchais était en fait un test similaire à la fonction vide en php fonctionnant dans un shell bash.
Après avoir lu les réponses, je me suis rendu compte que je ne pensais pas correctement dans bash, mais de toute façon, à ce moment-là, une fonction comme vide dans php aurait été très utile dans mon code bash.
Comme je pense que cela peut arriver à d’autres, j’ai décidé de convertir la fonction php empty en bash
selon le manuel php :
une variable est considérée comme vide si elle n'existe pas ou si sa valeur est l'une des suivantes:
Bien sûr, les cas nul et faux ne peuvent pas être convertis en bash, ils sont donc omis.
Exemple d'utilisation:
Démo:
l'extrait suivant:
les sorties:
Cela dit, dans une logique bash, les vérifications de zéro dans cette fonction peuvent entraîner des problèmes secondaires, toute personne utilisant cette fonction devrait évaluer ce risque et peut-être décider de supprimer ces vérifications en ne laissant que le premier.
la source
empty
- pourquoi avez-vous écrit[[ $( echo "1" ) ]] ; return
au lieu de simplementreturn 1
?l'ensemble if-then et -z est inutile.
la source
Ceci est vrai exactement quand $ FOO est défini et vide:
la source
Personnellement, préférez un moyen plus clair de vérifier:
la source
extension de la solution duffbeer703 :
la source
Mes 5 centimes: il existe aussi une syntaxe plus courte que
if ...
celle-ci:Cette ligne définira VALEUR si un argument a été fourni et imprimera un message d'erreur précédé du numéro de ligne du script en cas d'erreur (et mettra fin à l'exécution du script).
Vous trouverez un autre exemple dans le guide des abs (recherchez "Exemple 10-7").
la source
Pas une réponse exacte, mais a rencontré cette astuce. Si la chaîne que vous recherchez provient d'une "commande", vous pouvez alors la stocker dans un env. variable et ensuite l'exécuter à chaque fois pour l'instruction if, aucun crochet n'est requis!
Par exemple, cette commande, qui détermine si vous êtes sur debian:
grep debian /proc/version
exemple complet:
Il s’agit donc d’une manière indirecte (en l’exécutant à chaque fois) de rechercher une chaîne vide (il s’agit de rechercher une réponse d’erreur de la commande, mais il renvoie également une chaîne vide).
la source