Editar: Esta es una versión más completa que muestra más diferencias entre [
(aka test
) y [[
.
La siguiente tabla muestra que si una variable se cita o no, si usa corchetes simples o dobles y si la variable contiene solo un espacio son las cosas que afectan si el uso de una prueba con o sin -n/-z
es adecuado para verificar una 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 desea saber si una variable tiene una longitud distinta de cero, realice una de las siguientes acciones:
- cita la variable entre corchetes (columna 2a)
- usa
-n
y cita la variable entre corchetes (columna 4a)
- use corchetes dobles con o sin comillas y con o sin
-n
(columnas 1b - 4b)
Observe en la columna 1a que comienza en la fila etiquetada "dos" que el resultado indica que [
está evaluando el contenido de la variable como si fueran parte de la expresión condicional (el resultado coincide con la aserción implícita en la "T" o "F" en la columna de descripción). Cuando [[
se usa (columna 1b), el contenido variable se ve como una cadena y no se evalúa.
Los errores en las columnas 3a y 5a son causados por el hecho de que el valor de la variable incluye un espacio y la variable no está entre comillas. Nuevamente, como se muestra en las columnas 3b y 5b, [[
evalúa el contenido de la variable como una cadena.
En consecuencia, para las pruebas de cadenas de longitud cero, las columnas 6a, 5b y 6b muestran las formas correctas de hacerlo. También tenga en cuenta que cualquiera de estas pruebas se puede negar si la negación muestra una intención más clara que el uso de la operación opuesta. Por ejemplo: if ! [[ -n $var ]]
.
Si está utilizando [
, la clave para asegurarse de que no obtenga resultados inesperados es citar la variable. Usando [[
, no importa.
Los mensajes de error, que se están suprimiendo, son "operador unario esperado" u "operador binario esperado".
Este es el script que produjo la tabla anterior.
#!/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