sintaxis script operadores operaciones logicos con comparaciones cadenas bash shell if-statement

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