Edit: Ceci est une version plus complète qui montre plus de différences entre [
(aka test
) et [[
.
Le tableau suivant montre que le fait qu'une variable soit entre guillemets ou non, que vous utilisiez des crochets simples ou doubles et si la variable ne contienne qu'un espace sont les éléments qui déterminent si l'utilisation d'un test avec ou sans -n/-z
convient pour vérifier une variable.
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
Si vous voulez savoir si une variable est de longueur différente de zéro, effectuez l'une des opérations suivantes:
- citer la variable entre parenthèses simples (colonne 2a)
- utiliser
-n
et citer la variable entre parenthèses simples (colonne 4a)
- utiliser des crochets doubles avec ou sans guillemets et avec ou sans
-n
(colonnes 1b - 4b)
Notez dans la colonne 1a commençant à la ligne étiquetée «deux» que le résultat indique qu'il [
évalue le contenu de la variable comme s'il faisait partie de l'expression conditionnelle (le résultat correspond à l'assertion impliquée par le «T» ou «F» dans la colonne de description). Quand [[
est utilisé (colonne 1b), le contenu de la variable est vu comme une chaîne et n'est pas évalué.
Les erreurs dans les colonnes 3a et 5a sont causées par le fait que la valeur de la variable comprend un espace et que la variable n'est pas entre guillemets. Encore une fois, comme indiqué dans les colonnes 3b et 5b, [[
évalue le contenu de la variable sous forme de chaîne.
De même, pour les tests de chaînes de longueur nulle, les colonnes 6a, 5b et 6b montrent les bonnes façons de le faire. Notez également que n'importe lequel de ces tests peut être annulé si la négation montre une intention plus claire que l'utilisation de l'opération opposée. Par exemple: if ! [[ -n $var ]]
.
Si vous utilisez [
, la clé pour vous assurer que vous n'obtenez pas de résultats inattendus est de citer la variable. En utilisant [[
, cela n'a pas d'importance.
Les messages d'erreur, qui sont supprimés, sont "opérateur unaire attendu" ou "opérateur binaire attendu".
C'est le script qui a produit le tableau ci-dessus.
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF
["
vs[-n"
(la première question du PO) montre qu'ils sont complètement équivalents, non?[["
Il vaut mieux utiliser le plus puissant
[[
en ce qui concerne Bash.Cas habituels
Les deux constructions ci-dessus semblent propres et lisibles. Ils devraient suffire dans la plupart des cas.
Notez que nous n'avons pas besoin de citer les extensions de variables à l'intérieur
[[
car il n'y a aucun risque de fractionnement et de globalisation des mots .Pour éviter les plaintes douces de shellcheck à propos de
[[ $var ]]
et[[ ! $var ]]
, nous pourrions utiliser l'-n
option.Cas rares
Dans le cas rare où nous devions faire une distinction entre "être défini sur une chaîne vide" et "ne pas être défini du tout", nous pourrions utiliser ceux-ci:
Nous pouvons également utiliser le
-v
test:Articles et documentation connexes
Il existe de nombreux articles liés à ce sujet. Voici quelques-uns:
[[
vs[
[
VS[[
la source
Voici quelques tests supplémentaires
Vrai si la chaîne n'est pas vide:
Vrai si la chaîne est vide:
la source
La bonne réponse est la suivante:
Notez l'utilisation de
[[...]]
, qui gère correctement la citation des variables pour vous.la source
-n
quand ce n'est pas vraiment nécessaire dans Bash?Une manière alternative et peut-être plus transparente d'évaluer une variable d'environnement vide consiste à utiliser ...
la source
bash
est un outil plus pointu que ses prédécesseurs.[ "$ENV_VARIABLE" != "" ]
fonctionnera sur tous les shell avec unetest
implémentation compatible POSIX - pas seulement bash, mais ash / dash / ksh / etc.-a
ou-o
pour combiner des tests mais utilisez plutôt[ ... ] && [ ... ]
ou[ ... ] || [ ... ]
et les seuls cas de coin qui peuvent s'appliquer à l'utilisation des données de variables arbitraires dans un test sont fermés sans ambiguïté.Utilisez
case/esac
pour tester:la source
case
ça sert.case
fonctionne mieux lorsqu'il existe plus de deux alternatives.case
n'est pas destiné à ce type d'utilisation.