El uso de set -u no funciona como se esperaba

Estoy aprendiendo a usar de manera eficiente diferentes set opciones en mi script y encontré set -u que parece ser perfecto para salir de mi secuencia de comandos si una variable no se configura correctamente (por ejemplo, eliminar usuarios). Según la página man , set -u y set -e hace lo siguiente …

-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting. 

Creé un script de prueba para probar esta funcionalidad, pero no parece estar funcionando como se esperaba . ¿Quizás alguien podría explicarme mejor mi problema y dónde estoy malinterpretando? El guión de prueba está a continuación. Gracias.

set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3} 

Espero que el script muestre 0 y «Esto funciona» , y luego falla como ${testing2} no configurado.

En su lugar, se muestra 0 y «Esto funciona» , seguido de 0 y luego 0 Esto no debería aparecer

¿Alguien puede aportar algún conocimiento? Gracias.

Comentarios

  • Entonces, seguimiento … ¿hay alguna forma de convertir una variable en una cadena nula ilegal o generar un error? Yo ' supongo que no.

Responder

De » man Bash «:

Se establece un parámetro si se le ha asignado un valor. La cadena nula es un valor válido. Una vez que se establece una variable, se puede desarmar solo mediante el comando incorporado desarmar.

Cuando lo haga testing2= está configurando la variable en la cadena nula.

Cambie eso a unset testing2 y vuelva a intentarlo.


El set -e no ayuda en este caso, ya que una asignación nunca tiene un código de salida de 1. Intente esto para ver que el último comando ejecutado (la asignación) tiene un código de salida de 0, o lea esta pregunta :

$ false; a=""; echo $? 0 

Y también creo que el uso de set -e es más un problema que una solución.

Lo que puede generar un error con el uso de variables no configuradas es set -u:

#!/bin/bash set -u testing="This works" echo ${testing} unset testing2 echo ${testing2} testing3="This should not appear" echo ${testing3} 

El resultado será:

$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable 

Respuesta

testing2= establece la variable testing2 en una cadena vacía; la variable en realidad está configurada .

Sin embargo, si tuviera que ejecutar echo $testing99 en un shell Bash interactivo (sin configurar errexit, es decir, set -e), obtendría un error:

bash: testing99: unbound variable 

Aparte

Mientras probaba los scripts, descubrí que un shell interactivo no siempre sale al intentar expandir una variable que no se ha configurado mientras un shell no interactivo (ejecuta un script de shell) siempre sale de . Según la página de manual de POSIX para set:

-u El shell escribirá un mensaje de error estándar cuando intenta expandir una variable que no está configurada y sale inmediatamente. Un shell interactivo no saldrá.

Un shell Bash interactivo no saldrá a menos que errexit tenga también se ha configurado. Por otro lado, un shell de tablero interactivo no se cerrará, incluso si set -e se ha ejecutado previamente.

Comentarios

  • Si el guión no sale con set -e; set -u; unset aa; echo $ aa, entonces el guión es incorrecto.
  • @schily Cuando me di cuenta de esto por primera vez, pensé que los autores del guión sabían mejor que yo y que puede haber alguna ambigüedad en las especificaciones POSIX, pero habiendo marcado pubs.opengroup.org/onlinepubs/9699919799/utilities/… , estoy de acuerdo en que parece un error, bien.
  • Hay una regla simple: cuando tanto Korn Shell como Bourne Shell están de acuerdo y otra implementación de shell tiene una desviación, entonces el otro shell se comporta incorrectamente.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *