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
["
vs[-n"
(la primera pregunta del OP) muestra que son completamente equivalentes, ¿verdad?[["
Es mejor usar el más poderoso
[[
en lo que respecta a Bash.Casos habituales
Las dos construcciones anteriores se ven limpias y legibles. Deberían ser suficientes en la mayoría de los casos.
Tenga en cuenta que no necesitamos citar las expansiones variables en el interior,
[[
ya que no hay peligro de división de palabras y pegadura .Para evitar las quejas de Shellcheck sobre
[[ $var ]]
y[[ ! $var ]]
, podríamos usar la-n
opción.Casos raros
En el raro caso de que tengamos que hacer una distinción entre "estar configurado en una cadena vacía" frente a "no estar configurado en absoluto", podríamos usar estos:
También podemos usar la
-v
prueba:Publicaciones relacionadas y documentación
Hay muchas publicaciones relacionadas con este tema. Aquí hay algunos:
[[
vs[
[
vs[[
fuente
Aquí hay algunas pruebas más
Verdadero si la cadena no está vacía:
Verdadero si la cadena está vacía:
fuente
La respuesta correcta es la siguiente:
Tenga en cuenta el uso de
[[...]]
, que maneja correctamente la cita de las variables por usted.fuente
-n
cuando realmente no es necesario en Bash?Una forma alternativa y quizás más transparente de evaluar una variable de entorno vacía es usar ...
fuente
bash
Es una herramienta más afilada que sus predecesoras.[ "$ENV_VARIABLE" != "" ]
funcionará en cada shell con unatest
implementación compatible con POSIX , no solo bash, sino ash / dash / ksh / etc.-a
o-o
combine pruebas, sino que use[ ... ] && [ ... ]
o[ ... ] || [ ... ]
y los únicos casos de esquina que pueden aplicarse al uso de datos de variables arbitrarias en una prueba están cerrados sin ambigüedades.Use
case/esac
para probar:fuente
case
es para lo que está destinado.case
funciona mejor cuando hay más de dos alternativas.case
no está destinado a este tipo de uso.