Quel est le meilleur moyen de déterminer si une variable de bash est vide ("")?
J'ai entendu dire qu'il est recommandé que je fasse if [ "x$variable" = "x" ]
Est-ce la bonne façon? (il doit y avoir quelque chose de plus simple)
Quel est le meilleur moyen de déterminer si une variable de bash est vide ("")?
J'ai entendu dire qu'il est recommandé que je fasse if [ "x$variable" = "x" ]
Est-ce la bonne façon? (il doit y avoir quelque chose de plus simple)
Réponses:
Cela retournera true si une variable est non définie ou définie sur la chaîne vide ("").
if [ -z "$VAR" ];
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 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.
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:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
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:
if [[ -z $variable && ${variable+x} ]]
if [[ $variable ]]
a bien fonctionné pour moi et je n’avais même pas besoin de ce set -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. Le then
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:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -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:
+-------+-------+-----------+
VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | true | true | false |
| [ -z "${VAR+set}" ] | true | false | false |
| [ -z "${VAR-unset}" ] | false | true | false |
| [ -n "${VAR}" ] | false | false | true |
| [ -n "${VAR+set}" ] | false | true | true |
| [ -n "${VAR-unset}" ] | true | false | true |
+-----------------------+-------+-------+-----------+
La ${VAR+foo}
construction se développe en chaîne vide si VAR
est non défini ou to foo
si VAR
est défini sur n'importe quoi (y compris la chaîne vide).
La ${VAR-foo}
construction se développe à la valeur de VAR
if set (y compris set à la chaîne vide) et foo
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'utiliser red
si la variable COLOR
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 de test
) sont erronées. Si VAR
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.
[ -z "${VAR-set}" ]
.
set -u
ou set -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
export PORT=${MY_PORT:-5432}
Si la $MY_PORT
variable est vide, la valeur PORT
est 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.
set -o nounset
dans certains scripts.
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 -u
ou set -o nounset
), vous rencontrerez des problèmes avec ces deux méthodes. Il y a une solution simple à ceci:
[ -z "${foo:-}" ]
Note: cela laissera votre variable undef.
-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 [
ou test
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.
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 passed
if test -z "$var"
then
[[ $( echo "1" ) ]]
return
# Return true if var is zero (0 as an integer or "0" as a string)
elif [ "$var" == 0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
# Return true if var is 0.0 (0 as a float)
elif [ "$var" == 0.0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
fi
[[ $( echo "" ) ]]
}
Exemple d'utilisation:
if empty "${var}"
then
echo "empty"
else
echo "not empty"
fi
Démo:
l'extrait suivant:
#!/bin/bash
vars=(
""
0
0.0
"0"
1
"string"
" "
)
for (( i=0; i<${#vars[@]}; i++ ))
do
var="${vars[$i]}"
if empty "${var}"
then
what="empty"
else
what="not empty"
fi
echo "VAR \"$var\" is $what"
done
exit
les sorties:
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.
empty
- pourquoi avez-vous écrit [[ $( echo "1" ) ]] ; return
au lieu de simplement return 1
?
l'ensemble if-then et -z est inutile.
["$ foo"] && echo "foo n'est pas vide" ["$ foo"] || echo "foo est en effet vide"
Ceci est vrai exactement quand $ FOO est défini et vide:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Personnellement, préférez un moyen plus clair de vérifier:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
extension de la solution duffbeer703 :
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
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:
grep debian /proc/version
exemple complet:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
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).