if, elif, else problemas de declaración en Bash

359

Parece que no puedo resolver cuál es el problema con la siguiente ifdeclaración en relación con el elify then. Tenga en cuenta printfque todavía está en desarrollo. Simplemente no he podido probarlo todavía en la declaración, por lo que es muy probable que esté equivocado.

El error que obtengo es:

./timezone_string.sh: line 14: syntax error near unexpected token `then'
./timezone_string.sh: line 14: `then'

Y la afirmación es así.

if [ "$seconds" -eq 0 ];then
   $timezone_string="Z"
elif[ "$seconds" -gt 0 ]
then
   $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
   echo "Unknown parameter"
fi
StuStirling
fuente
77
Me pregunto por qué necesitamos la thendeclaración en ify elifpero no en else, y también en general.
@ w17t, porque necesitamos separar la condición de la secuencia.
Sasha
3
@codeforester No veo mucha lógica en marcar una pregunta de 500K vistas como un duplicado a una que solo tiene 5K
fedorqui 'SO deja de dañar'
El uso de algunas herramientas de formato automático de código puede ayudarlo agregando / eliminando automáticamente espacios alrededor de los corchetes. Puede buscar complementos para su editor.
Nj Subedi

Respuestas:

453

Falta un espacio entre elify [:

elif[ "$seconds" -gt 0 ]

debiera ser

elif [ "$seconds" -gt 0 ]

Como veo que esta pregunta está obteniendo muchas vistas, es importante indicar que la sintaxis a seguir es:

if [ conditions ]
# ^ ^          ^

lo que significa que se necesitan espacios alrededor de los corchetes . De lo contrario, no funcionará. Esto se debe a que [sí mismo es un comando.

La razón por la que no está viendo algo así como elif[: command not found(o similar) es que después de ver ify then, la cáscara está buscando, ya sea elif, elseo fi. Sin embargo, encuentra otro then(después del formato incorrecto elif[). Solo después de haber analizado la declaración, se ejecutará (y se generará un mensaje de error como elif[: command not found).

fedorqui 'así que deja de dañar'
fuente
33
La razón por la que los paréntesis necesitan espacios es porque son solo accesos directos para programas reales (al menos el primer paréntesis, el segundo es solo azúcar sintáctico, según tengo entendido). Para darle sentido, vea la página de manual real para el soporte izquierdo:$ man [
Michael Johansen
3
¿No se supone que esta publicación está cerrada como error tipográfico?
zx8754
3
@ zx8754 podría haber sido, pero no se convirtió en una forma canónica de corregir este error, que parece bastante útil (360K vistas y contando).
fedorqui 'SO deja de dañar'
3
Algunos de mis colegas no entienden el concepto de "espacio" o "estilo de codificación", por lo que esto podría no ser un error tipográfico.
juzzlin
3
[es una especie de alias para el comando de prueba. Es por eso que se requiere el carácter en blanco. if test "$seconds" -eq 0; then ... fies equivalente a if [ "$seconds" -eq 0 ];then ... fi ]. @LeiYang man testes lo que realmente estás buscando
Melicerte
304

Tiene algunos problemas de sintaxis con su script. Aquí hay una versión fija:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi
anubhava
fuente
76
Por extraño que parezca, esta fue la única construcción completa y simple de bash "si-entonces-otro" que encontré fácilmente en stackexchange ... gracias.
Comodín el
1
La sangría es opcional. el intérprete puede (y debe) ser #!/bin/sh.
3
@ Chinggis6 Total sin sentido, el intérprete podría ser, #!/bin/shpero no tiene que hacerlo.
Camusensei
44
@Camusensei no es una tontería total, ya que shse puede usar en su lugar para una mayor compatibilidad (no todas las distribuciones * nix tienen bash como shell predeterminado (algunas tienen ksh o ash pero la mayoría de ellas dependen del estándar shpara funcionar). Además, si bash es específico o funciones avanzadas que no se está utilizando en la secuencia de comandos a continuación, 'sh' se debe utilizar como el intérprete (una razón más por ello), ya que puede manejar el guión por sí mismo.
66
@ Chinggis6 Verdadero, mala elección de palabras de mi lado.
Camusensei
25

[es un comando (o un incorporado en algunos shells). Debe estar separado por espacios en blanco de la declaración anterior:

elif [
choroba
fuente
3
Es reemplazado por un incorporado en bash, pero su mensaje sigue siendo correcto. solía type -a [ver eso.
Camusensei
También es un binario que siempre me pareció extraño.
mr.zog
4

Te recomendaría que eches un vistazo a los conceptos básicos de acondicionamiento en bash.

El símbolo "[" es un comando y debe tener un espacio en blanco antes. Si no asigna espacios en blanco después de su elif, el sistema interpreta elif [ como un comando particular que definitivamente no es lo que desearía en este momento.

Uso:

elif(A COMPULSORY WHITESPACE WITHOUT PARENTHESIS)[(A WHITE SPACE WITHOUT PARENTHESIS)conditions(A WHITESPACE WITHOUT PARENTHESIS)]

En resumen, edite su segmento de código para:

elif [ "$seconds" -gt 0 ]

Estaría bien sin errores de compilación. Su segmento de código final debería verse así:

#!/bin/sh    
if [ "$seconds" -eq 0 ];then
       $timezone_string="Z"
    elif [ "$seconds" -gt 0 ]
    then
       $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
    else
       echo "Unknown parameter"
    fi
Señor weirdo
fuente
2

Falta espacio entre elify [descansar su programa es correcto. necesita corregirlo y verificarlo. Aquí está el programa fijo:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

enlace útil relacionado con esta declaración bash if else

John Walsh
fuente