Saltar al contenido

bash – ¿Cómo puedo declarar y usar variables booleanas en un script de shell?

octubre 30, 2021
apple touch icon@2

Parece haber un malentendido aquí sobre el Bash incorporado. true, y más específicamente, sobre cómo Bash expande e interpreta las expresiones entre corchetes.

El código en la respuesta de miku no tiene absolutamente nada que ver con el Bash incorporado true, ni /bin/true, ni ningún otro sabor del true mando. En este caso, true no es más que una simple cadena de caracteres, y ninguna llamada a la true command / builtin nunca se realiza, ni por la asignación de variable, ni por la evaluación de la expresión condicional.

El siguiente código es funcionalmente idéntico al código en la respuesta del miku:

the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
    echo 'Be careful not to fall off!'
fi

los solamente La diferencia aquí es que los cuatro caracteres que se comparan son ‘y’, ‘e’, ​​’a’ y ‘h’ en lugar de ‘t’, ‘r’, ‘u’ y ‘e’. Eso es todo. No se ha hecho ningún intento de llamar a un comando o de un nombre incorporado yeah, ni hay (en el ejemplo de miku) ningún tipo de manejo especial cuando Bash analiza el token true. Es solo una cadena, y una completamente arbitraria en eso.

Actualización (2014-02-19): Después de seguir el enlace en la respuesta de miku, ahora veo de dónde proviene parte de la confusión. La respuesta de Miku usa corchetes simples, pero el fragmento de código al que se vincula no usa corchetes. Es solo:

the_world_is_flat=true
if $the_world_is_flat; then
  echo 'Be careful not to fall off!'
fi

Ambos fragmentos de código comportarse de la misma manera, pero los soportes cambian por completo lo que sucede debajo del capó.

Esto es lo que hace Bash en cada caso:

Sin corchetes:

  1. Expandir la variable $the_world_is_flat a la cuerda "true".
  2. Intenta analizar la cadena "true" como un comando.
  3. Encuentra y ejecuta el true comando (ya sea incorporado o /bin/true, dependiendo de la versión de Bash).
  4. Compare el código de salida del true comando (que siempre es 0) con 0. Recuerde que en la mayoría de los shells, un código de salida de 0 indica éxito y cualquier otra cosa indica falla.
  5. Dado que el código de salida fue 0 (éxito), ejecute el if declaraciones then cláusula

Soportes:

  1. Expandir la variable $the_world_is_flat a la cuerda "true".
  2. Analizar la expresión condicional ahora completamente expandida, que tiene la forma string1 = string2. los = el operador es de bash comparación de cadenas operador. Entonces…
  3. Haga una comparación de cadenas en "true" y "true".
  4. Sí, las dos cadenas eran iguales, por lo que el valor del condicional es verdadero.
  5. Ejecute el if declaraciones then cláusula.

El código sin corchetes funciona, porque el true El comando devuelve un código de salida de 0, que indica éxito. El código entre corchetes funciona, porque el valor de $the_world_is_flat es idéntico al literal de cadena true en el lado derecho de la =.

Solo para llevar el punto a casa, considere los siguientes dos fragmentos de código:

Este código (si se ejecuta con privilegios de root) reiniciará su computadora:

var=reboot
if $var; then
  echo 'Muahahaha! You are going down!'
fi

Este código simplemente imprime «Buen intento». No se llama al comando de reinicio.

var=reboot
if [ $var ]; then
  echo 'Nice try.'
fi

Actualización (2014-04-14) Para responder a la pregunta en los comentarios sobre la diferencia entre = y ==: AFAIK, no hay diferencia. los == operator es un sinónimo específico de Bash para =y, por lo que he visto, funcionan exactamente igual en todos los contextos.

Tenga en cuenta, sin embargo, que estoy hablando específicamente de la = y == operadores de comparación de cadenas utilizados en [ ] o [[ ]] pruebas. No estoy sugiriendo eso = y == son intercambiables En todas partes en bash.

Por ejemplo, obviamente no puede hacer una asignación de variables con ==, tal como var=="foo" (bueno técnicamente tu pueden hacer esto, pero el valor de var estarán "=foo", porque Bash no ve un == operador aquí, está viendo un = (asignación) operador, seguido del valor literal ="foo", que simplemente se convierte en "=foo").

Además, aunque = y == son intercambiables, debe tener en cuenta que cómo funcionan esas pruebas lo hace depende de si lo estás usando en el interior [ ] o [[ ]], y también sobre si se citan o no los operandos. Puedes leer más sobre eso en Guía avanzada de secuencias de comandos de Bash: 7.3 Otros operadores de comparación (desplácese hacia abajo hasta la discusión de = y ==).

close