¿Eso incluye si una variable SE ESTABLECE en un valor de ""?
Brent
11
Sí, lo hace ... "-z" prueba una cadena de longitud cero.
David Z
9191
if [ ! -z "$VAR" ];
Aaron Copley
263
lo contrario de -zes-nif [ -n "$VAR" ];
Felipe Alvarez
19
Las comillas dobles aseguran que la variable no se divida. Un simple $varen una línea de comando se dividirá por su espacio en blanco en una lista de parámetros, mientras "$var"que siempre será un solo parámetro. Citar variables a menudo es una buena práctica y le impide tropezar con nombres de archivos que contienen espacios en blanco (entre otras cosas). Ejemplo: después de hacerlo a="x --help", intente cat $a, le dará la página de ayuda cat. Luego intente cat "$a", lo dirá (generalmente) cat: x --help: No such file or directory. En resumen, cite temprano y cite a menudo y casi nunca se arrepentirá.
Score_Under
247
En Bash, cuando no le preocupa la portabilidad a los shells que no lo admiten, siempre debe usar la sintaxis de doble paréntesis:
Eso if [[ $variable ]]funcionó bien para mí y ni siquiera necesitaba lo set -uque requería una de las otras soluciones propuestas.
Teemu Leisti
3
Creo que esto es mejor que la respuesta aceptada.
qed
2
¿Por qué recomienda una característica no portátil cuando hacerlo no ofrece ningún beneficio?
Alastair Irvine
19
@AlastairIrvine: Menciono la portabilidad en la primera oración de mi respuesta, el título y el cuerpo de la pregunta contienen la palabra "Bash" y la pregunta está etiquetada como bash , y la estructura de doble parche ofrece claras ventajas de muchas maneras. Y no recomiendo mezclar estilos de corchetes por razones de consistencia y facilidad de mantenimiento. Si necesita la máxima portabilidad del mínimo común denominador, use en shlugar de Bash. Si necesita las capacidades mejoradas que proporciona, use Bash y úselo completamente.
Dennis Williamson
2
@BrunoBronosky: Revertí la edición. No hay requisitos para ;al final. El thenpuede estar en la siguiente línea sin punto y coma.
Dennis Williamson el
230
Una variable en bash (y cualquier shell compatible con POSIX) puede estar en uno de tres estados:
desarmado
establecer en la cadena vacía
establecido en una cadena no vacía
La mayoría de las veces solo necesita saber si una variable está establecida en una cadena no vacía, pero ocasionalmente es importante distinguir entre unset y set en la cadena vacía.
Los siguientes son ejemplos de cómo puede probar las diversas posibilidades, y funciona en bash o en cualquier shell compatible con POSIX:
if[-z "${VAR}"];then
echo "VAR is unset or set to the empty string"fiif[-z "${VAR+set}"];then
echo "VAR is unset"fiif[-z "${VAR-unset}"];then
echo "VAR is set to the empty string"fiif[-n "${VAR}"];then
echo "VAR is set to a non-empty string"fiif[-n "${VAR+set}"];then
echo "VAR is set, possibly to the empty string"fiif[-n "${VAR-unset}"];then
echo "VAR is either unset or set to a non-empty string"fi
Aquí está lo mismo pero en forma de tabla práctica:
La ${VAR+foo}construcción se expande a la cadena vacía si no VARestá establecida o foosi VARse establece en cualquier cosa (incluida la cadena vacía).
La ${VAR-foo}construcción se expande al valor de VARif set (incluido el set a la cadena vacía) y fooif unset. Esto es útil para proporcionar valores predeterminados reemplazables por el usuario (por ejemplo, ${COLOR-red}dice usar a redmenos que la variable COLORse haya establecido en algo).
La razón por la [ x"${VAR}" = x ]que a menudo se recomienda para probar si una variable está desarmada o configurada en la cadena vacía es porque algunas implementaciones del [comando (también conocido como test) tienen errores. Si VARse establece en algo así -n, entonces algunas implementaciones harán lo incorrecto cuando se den [ "${VAR}" = "" ]porque el primer argumento [se interpreta erróneamente como el -noperador, no como una cadena.
La prueba de una variable establecida en la cadena vacía también se puede hacer usando [ -z "${VAR-set}" ].
nwellnhof
@nwellnhof: ¡Gracias! Actualicé mi respuesta para usar la sintaxis más breve.
Richard Hansen
¿Cuál es la diferencia entre la primera y la última construcción? Ambos corresponden a "VAR está desarmado o configurado en una cadena no vacía".
Faheem Mitha
1
@ FaheemMitha: No es tu culpa, mi respuesta fue difícil de leer. Agregué una tabla para que la respuesta sea más clara.
Richard Hansen
2
Los cheques sin configurar no son confiables. Si el usuario llamó set -uo set -o nounseten bash, entonces la prueba solo dará como resultado el error "bash: VAR: variable independiente". Visite stackoverflow.com/a/13864829 para obtener una verificación sin configurar más confiable. Mi opción para verificar si una variable es nula o no está establecida [ -z "${VAR:-}" ]. Mi verificación de si una variable no está vacía es [ "${VAR:-}" ].
Kevin Jin
38
-z Es la mejor manera.
Otra opción que he usado es establecer una variable, pero puede ser anulada por otra variable, por ejemplo
export PORT=${MY_PORT:-5432}
Si la $MY_PORTvariable está vacía, PORTse establece en 5432; de lo contrario, PORT se establece en el valor de MY_PORT. Tenga en cuenta que la sintaxis incluye los dos puntos y el guión.
Una alternativa que he visto [ -z "$foo" ]es la siguiente, sin embargo, no estoy seguro de por qué las personas usan este método, ¿alguien sabe?
["x${foo}"="x"]
De todos modos, si no permite variables no establecidas (ya sea por set -uo set -o nounset), entonces tendrá problemas con ambos métodos. Hay una solución simple para esto:
Hay un comentario sobre la alternativa -zen pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Básicamente, no está destinado a ser una alternativa a -z. Más bien, se ocupa de los casos en que $foopodría expandir a algo que comienza con un meta que [o testse confunde con. Poner un no metacarácter arbitrario al principio elimina esa posibilidad.
James Sneeringer el
6
La pregunta pregunta cómo verificar si una variable es una cadena vacía y las mejores respuestas ya están dadas para eso.
Pero llegué aquí después de un período de programación en php y lo que realmente estaba buscando era una verificación como la función vacía en php trabajando en un shell bash.
Después de leer las respuestas, me di cuenta de que no estaba pensando correctamente en bash, pero de todos modos en ese momento una función como vacío en php hubiera sido muy útil en mi código bash.
Como creo que esto puede sucederle a otros, decidí convertir la función vacía de php en bash
De acuerdo con el manual de php : una variable se considera vacía si no existe o si su valor es uno de los siguientes:
"" (una cadena vacía)
0 (0 como un entero)
0.0 (0 como flotante)
"0" (0 como una cadena)
una matriz vacía
una variable declarada, pero sin un valor
Por supuesto, los casos nulo y falso no se pueden convertir en bash, por lo que se omiten.
function empty
{local var="$1"# Return true if:# 1. var is a null string ("" as empty string)# 2. a non set variable is passed# 3. a declared variable or array but without a value is passed# 4. an empty array is passedif test -z "$var"then[[ $( echo "1")]]return# Return true if var is zero (0 as an integer or "0" as a string)elif["$var"==02>/dev/null ]then[[ $( echo "1")]]return# Return true if var is 0.0 (0 as a float)elif["$var"==0.02>/dev/null ]then[[ $( echo "1")]]returnfi[[ $( echo "")]]}
Ejemplo de uso:
if empty "${var}"then
echo "empty"else
echo "not empty"fi
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
Dicho esto, en una lógica bash, las comprobaciones de cero en esta función pueden causar problemas secundarios en mi humilde opinión, cualquiera que use esta función debería evaluar este riesgo y tal vez decidir cortar esas comprobaciones dejando solo el primero.
También fallará en algunos shells si foo comienza con un guión, ya que se interpreta como una opción. Por ejemplo, en solaris ksh , zsh y bash no son un problema, sh y / bin / test fallarán
ktf
4
Esto es cierto exactamente cuando $ FOO está configurado y vacío:
La pregunta era sobre bash. Estoy usando bash Funciona bien para mi ¿De qué estás hablando exactamente?
Fedir RYKHTIK
2
Si usa Bash, debe usar corchetes dobles. Mi comentario anterior fue una simple declaración de hechos para aquellos que podrían leer su respuesta y estar usando un shell diferente.
Mis 5 centavos: también hay una sintaxis más corta que if ...esta:
VALUE="${1?"Usage: $0 value"}"
Esta línea establecerá VALOR si se ha proporcionado un argumento e imprimirá un mensaje de error antepuesto con el número de línea del script en caso de error (y terminará la ejecución del script).
Se puede encontrar otro ejemplo en la guía de abdominales (busque el «Ejemplo 10-7»).
No es una respuesta exacta, pero me encontré con este truco. Si la cadena que busca proviene de "un comando", puede almacenar el comando en un entorno. variable y luego ejecutarlo cada vez para la instrucción if, ¡entonces no se necesitan corchetes!
Por ejemplo, este comando, que determina si estás en Debian:
Entonces, esto es como una forma indirecta (volver a ejecutarlo cada vez) para verificar una cadena vacía (está comprobando la respuesta de error del comando, pero también está devolviendo una cadena vacía).
Respuestas:
Esto devolverá verdadero si una variable se desarma o establece en la cadena vacía ("").
fuente
if [ ! -z "$VAR" ];
-z
es-n
if [ -n "$VAR" ];
$var
en una línea de comando se dividirá por su espacio en blanco en una lista de parámetros, mientras"$var"
que siempre será un solo parámetro. Citar variables a menudo es una buena práctica y le impide tropezar con nombres de archivos que contienen espacios en blanco (entre otras cosas). Ejemplo: después de hacerloa="x --help"
, intentecat $a
, le dará la página de ayudacat
. Luego intentecat "$a"
, lo dirá (generalmente)cat: x --help: No such file or directory
. En resumen, cite temprano y cite a menudo y casi nunca se arrepentirá.En Bash, cuando no le preocupa la portabilidad a los shells que no lo admiten, siempre debe usar la sintaxis de doble paréntesis:
Cualquiera de los siguientes:
En Bash, usando corchetes dobles, las comillas no son necesarias. Se puede simplificar la prueba para una variable que hace contener un valor de:
Esta sintaxis es compatible con ksh (al menos ksh93, de todos modos). No funciona en POSIX puro o shells Bourne anteriores como sh o dash.
Vea mi respuesta aquí y BashFAQ / 031 para obtener más información sobre las diferencias entre corchetes dobles y simples.
Puede probar para ver si una variable está específicamente desarmada (a diferencia de una cadena vacía):
donde la "x" es arbitraria.
Si desea saber si una variable es nula pero no está desarmada:
fuente
if [[ $variable ]]
funcionó bien para mí y ni siquiera necesitaba loset -u
que requería una de las otras soluciones propuestas.sh
lugar de Bash. Si necesita las capacidades mejoradas que proporciona, use Bash y úselo completamente.;
al final. Elthen
puede estar en la siguiente línea sin punto y coma.Una variable en bash (y cualquier shell compatible con POSIX) puede estar en uno de tres estados:
La mayoría de las veces solo necesita saber si una variable está establecida en una cadena no vacía, pero ocasionalmente es importante distinguir entre unset y set en la cadena vacía.
Los siguientes son ejemplos de cómo puede probar las diversas posibilidades, y funciona en bash o en cualquier shell compatible con POSIX:
Aquí está lo mismo pero en forma de tabla práctica:
La
${VAR+foo}
construcción se expande a la cadena vacía si noVAR
está establecida ofoo
siVAR
se establece en cualquier cosa (incluida la cadena vacía).La
${VAR-foo}
construcción se expande al valor deVAR
if set (incluido el set a la cadena vacía) yfoo
if unset. Esto es útil para proporcionar valores predeterminados reemplazables por el usuario (por ejemplo,${COLOR-red}
dice usar ared
menos que la variableCOLOR
se haya establecido en algo).La razón por la
[ x"${VAR}" = x ]
que a menudo se recomienda para probar si una variable está desarmada o configurada en la cadena vacía es porque algunas implementaciones del[
comando (también conocido comotest
) tienen errores. SiVAR
se establece en algo así-n
, entonces algunas implementaciones harán lo incorrecto cuando se den[ "${VAR}" = "" ]
porque el primer argumento[
se interpreta erróneamente como el-n
operador, no como una cadena.fuente
[ -z "${VAR-set}" ]
.set -u
oset -o nounset
en bash, entonces la prueba solo dará como resultado el error "bash: VAR: variable independiente". Visite stackoverflow.com/a/13864829 para obtener una verificación sin configurar más confiable. Mi opción para verificar si una variable es nula o no está establecida[ -z "${VAR:-}" ]
. Mi verificación de si una variable no está vacía es[ "${VAR:-}" ]
.-z
Es la mejor manera.Otra opción que he usado es establecer una variable, pero puede ser anulada por otra variable, por ejemplo
Si la
$MY_PORT
variable está vacía,PORT
se establece en 5432; de lo contrario, PORT se establece en el valor deMY_PORT
. Tenga en cuenta que la sintaxis incluye los dos puntos y el guión.fuente
set -o nounset
en algunos guiones.Si está interesado en distinguir los casos de estado de conjunto vacío frente a estado no establecido, mire la opción -u para bash:
fuente
Una alternativa que he visto
[ -z "$foo" ]
es la siguiente, sin embargo, no estoy seguro de por qué las personas usan este método, ¿alguien sabe?De todos modos, si no permite variables no establecidas (ya sea por
set -u
oset -o nounset
), entonces tendrá problemas con ambos métodos. Hay una solución simple para esto:Nota: esto dejará su variable undef.
fuente
-z
en pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Básicamente, no está destinado a ser una alternativa a-z
. Más bien, se ocupa de los casos en que$foo
podría expandir a algo que comienza con un meta que[
otest
se confunde con. Poner un no metacarácter arbitrario al principio elimina esa posibilidad.La pregunta pregunta cómo verificar si una variable es una cadena vacía y las mejores respuestas ya están dadas para eso.
Pero llegué aquí después de un período de programación en php y lo que realmente estaba buscando era una verificación como la función vacía en php trabajando en un shell bash.
Después de leer las respuestas, me di cuenta de que no estaba pensando correctamente en bash, pero de todos modos en ese momento una función como vacío en php hubiera sido muy útil en mi código bash.
Como creo que esto puede sucederle a otros, decidí convertir la función vacía de php en bash
De acuerdo con el manual de php :
una variable se considera vacía si no existe o si su valor es uno de los siguientes:
Por supuesto, los casos nulo y falso no se pueden convertir en bash, por lo que se omiten.
Ejemplo de uso:
Demostración:
el siguiente fragmento:
salidas:
Dicho esto, en una lógica bash, las comprobaciones de cero en esta función pueden causar problemas secundarios en mi humilde opinión, cualquiera que use esta función debería evaluar este riesgo y tal vez decidir cortar esas comprobaciones dejando solo el primero.
fuente
empty
: ¿por qué escribiste en[[ $( echo "1" ) ]] ; return
lugar de simplementereturn 1
?todo el if-then y -z son innecesarios.
fuente
Esto es cierto exactamente cuando $ FOO está configurado y vacío:
fuente
Personalmente prefiero una forma más clara de verificar:
fuente
extensión oneliner de la solución de duffbeer703 :
fuente
Mis 5 centavos: también hay una sintaxis más corta que
if ...
esta:Esta línea establecerá VALOR si se ha proporcionado un argumento e imprimirá un mensaje de error antepuesto con el número de línea del script en caso de error (y terminará la ejecución del script).
Se puede encontrar otro ejemplo en la guía de abdominales (busque el «Ejemplo 10-7»).
fuente
No es una respuesta exacta, pero me encontré con este truco. Si la cadena que busca proviene de "un comando", puede almacenar el comando en un entorno. variable y luego ejecutarlo cada vez para la instrucción if, ¡entonces no se necesitan corchetes!
Por ejemplo, este comando, que determina si estás en Debian:
grep debian /proc/version
ejemplo completo:
Entonces, esto es como una forma indirecta (volver a ejecutarlo cada vez) para verificar una cadena vacía (está comprobando la respuesta de error del comando, pero también está devolviendo una cadena vacía).
fuente