Como programador principalmente de Java, encuentro el bash if
–then
construir bastante confuso, especialmente con respecto a los espacios en blanco. ¿Alguien puede explicar por qué funciona el primero, pero no el segundo o el tercero?
#works
if [ -n $1 ]; then echo "parameterized"; fi
#output: ./links: Zeile 1: [-n: Kommando nicht gefunden.
if [-n $1 ]; then echo "parameterized"; fi
#output: ./links: Zeile 1: [: Fehlende `]'
if [ -n $1]; then echo "parameterized"; fi
Respuesta aceptada:
La inconsistencia se debe en gran parte a razones históricas.
El uso de corchetes como comando condicional se produjo después del uso de corchetes en patrones comodín. Entonces en ese momento [ -n foo ]
entró en escena, [foo]
ya significaba “un archivo cuyo nombre es f
o o
”. Si bien pocos usos del operador de corchetes en la práctica habrían entrado en conflicto con los usos realistas de los corchetes en los comodines, los autores optaron por no arriesgarse a romper los scripts existentes cambiando la sintaxis. Esta elección de diseño también facilitó la implementación:inicialmente [
se implementó como un comando externo, lo que no se podría haber hecho si el espacio después de [
había sido opcional. (Los sistemas modernos todavía tienen [
como un comando externo, pero casi todos los shells modernos también lo tienen incorporado).
Por razones similares, su código de "trabajo" es incorrecto en la mayoría de las circunstancias. $1
no significa "el valor del parámetro 1":significa "tomar el valor del parámetro 1, dividirlo en palabras separadas en espacios en blanco (o cualquiera que sea el valor de IFS
is), e interpretar cada palabra como un patrón global”. La forma de escribir “el valor del parámetro 1” requiere comillas dobles:"$1"
. Consulte ¿Cuándo son necesarias las comillas dobles? para el meollo del asunto. No necesitas entender esto; todo lo que necesita recordar es:siempre ponga comillas dobles alrededor de las sustituciones de variables "$foo"
y sustituciones de comandos "$(foo)"
. Así:
if [ -n "$1" ]; then …
En bash, ksh y zsh, pero no en simple sh, también puede usar corchetes dobles. Corchetes simples [ … ]
se analizan como un comando ordinario (y de hecho [
es un comando ordinario, aunque generalmente integrado). Los corchetes dobles son una construcción sintáctica separada y puede omitir las comillas dobles la mayor parte del tiempo.
if [[ -n $1 ]]; then …
Sin embargo, hay una excepción:[[ "$foo" = "$bar" ]]
para probar si las dos variables tienen el mismo valor requiere comillas dobles alrededor de $bar
, de lo contrario $bar
se interpreta como un patrón comodín. Nuevamente, en lugar de recordar los detalles, también podría usar comillas dobles todo el tiempo.