bash - operaciones - operadores logicos shell script
Prueba de cadena de longitud distinta de cero en Bash:[-n "$ var"] o (6)
Aquí hay algunas pruebas más
Verdadero si la cadena no está vacía:
[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"
Verdadero si la cadena está vacía:
[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"
He visto bash scripts probar cadenas de longitud distinta de cero de dos formas diferentes. La mayoría de los scripts usan la opción -n:
#!/bin/bash
# With the -n option
if [ -n "$var" ]; then
# Do something when var is non-zero length
fi
Pero la opción -n no es realmente necesaria:
# Without the -n option
if [ "$var" ]; then
# Do something when var is non-zero length
fi
¿Cuál es la mejor manera?
Del mismo modo, ¿cuál es la mejor manera de probar la longitud cero?
if [ -z "$var" ]; then
# Do something when var is zero-length
fi
o
if [ ! "$var" ]; then
# Do something when var is zero-length
fi
La respuesta correcta es la siguiente:
if [[ -n $var ]] ; then
blah
fi
Tenga en cuenta el uso de [[...]]
, que maneja correctamente citando las variables por usted.
Publicando esta respuesta ya que esta publicación está etiquetada como simplemente bash.
Es mejor usar el más poderoso [[
en lo que a Bash se refiere].
Casos usuales
if [[ $var ]]; then # var is set and it is not empty
if [[ ! $var ]]; then # var is not set or it is set to an empty string
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 de variables dentro de [[
ya que no hay peligro de división de palabras ni de globbing .
Casos raros
En el raro caso de que tengamos que hacer una distinción entre "estar configurado en una cadena vacía" vs "no estar configurado en absoluto", podríamos utilizar estos:
if [[ ${var+x} ]]; then # var is set but it could be empty
if [[ ! ${var+x} ]]; then # var is not set
if [[ ${var+x} && ! $var ]]; then # var is set and is empty
También podemos usar la prueba -v
:
if [[ -v var ]]; then # var is set but it could be empty
if [[ ! -v var ]]; then # var is not set
if [[ -v var && ! $var ]]; then # var is set and is empty
Más discusión
Hay un montón de preguntas y respuestas relacionadas con esto. Aquí hay algunos:
- ¿Cómo verificar si una variable está configurada en Bash?
- ¿Los corchetes dobles [[] son preferibles a los corchetes individuales [] en Bash?
- ¿Cuál es la diferencia entre los corchetes simples y dobles en Bash?
- Una excelente answer de mklement0 donde habla sobre
[[
vs[
Una forma alternativa y quizás más transparente de evaluar una variable env vacía es usar ...
if [ "x$ENV_VARIABLE" != "x" ] ; then
echo ''ENV_VARIABLE contains something''
fi
use case/esac
para probar
case "$var" in
"") echo "zero length";;
esac
Editar: Esta es una versión más completa que muestra más diferencias entre [
( test
aka) y [[
.
La siguiente tabla muestra que si una variable se cita o no, si se usan 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:
- cite la variable entre paréntesis (columna 2a)
- use
-n
y cite la variable entre paréntesis (columna 4a) - use corchetes dobles con o sin comillas y con o sin
-n
(columnas 1b - 4b)
Observe en la columna 1a comenzando en la fila etiquetada "dos" que el resultado indica que [
está evaluando los contenidos de la variable como si fueran parte de la expresión condicional (el resultado coincide con la afirmación implícita en la "T" o "F") en la columna de descripción). Cuando se usa [[
(columna 1b), el contenido de la 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á citada. De nuevo, como se muestra en las columnas 3b y 5b, [[
evalúa los contenidos de la variable como una cadena.
Si usa [
, la clave para asegurarse de no obtener resultados inesperados es citar la variable. Usando [[
, no importa.
Los mensajes de error que se suprimen son "operador unario esperado" u "operador binario esperado".
Esta es la secuencia de comandos que produjo la tabla de arriba.
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf "%-${w}s" "true"; }
f () { [[ $? == 1 ]] && printf "%-${w}s" "false " || printf "%-${w}s" "-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"''
while read -r d t
do
printf "%-${dw}s: " "$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