Parece que hay algunos malentendidos aquí sobre el Bash incorporado true
, y más específicamente, sobre cómo Bash expande e interpreta las expresiones entre paréntesis.
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
comando. En este caso, true
no es más que una simple cadena de caracteres, y nunca se realiza ninguna llamada al true
comando / incorporado, ni por la asignación de variables, ni por la evaluación de la expresión condicional.
El siguiente código es funcionalmente idéntico al código en la respuesta de miku:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
La única 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. No se ha intentado llamar a un comando o 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 completamente arbitraria.
Actualización (19/02/2014): 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 enlaza 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 se comportarán la misma manera, pero los corchetes cambian por completo lo que sucede debajo del capó.
Esto es lo que Bash está haciendo en cada caso:
Sin corchetes:
- Expande la variable
$the_world_is_flat
a la cadena "true"
.
- Intente analizar la cadena
"true"
como un comando.
- Busque y ejecute el
true
comando (ya sea un incorporado o /bin/true
, dependiendo de la versión de Bash).
- 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.
- Como el código de salida fue 0 (correcto), ejecute la cláusula de la
if
declaraciónthen
Soportes:
- Expande la variable
$the_world_is_flat
a la cadena "true"
.
- Analiza la expresión condicional ahora completamente expandida, que es de la forma
string1 = string2
. El =
operador es la comparación de cadenas de bash operador de . Entonces...
- Haga una comparación de cadenas en
"true"
y "true"
.
- Sí, las dos cadenas eran iguales, por lo que el valor del condicional es verdadero.
- Ejecute la cláusula de la
if
declaración then
.
El código sin corchetes funciona, porque el true
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 =
.
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". El comando de reinicio no se llama.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Actualización (2014-04-14) Para responder la pregunta en los comentarios sobre la diferencia entre =
y ==
: AFAIK, no hay diferencia. El ==
operador es un sinónimo específico de Bash y =
, por lo que he visto, funcionan exactamente igual en todos los contextos.
Nótese, sin embargo, que estoy hablando específicamente acerca de las =
y ==
los operadores de comparación de cadena utilizadas por cualquiera [ ]
o [[ ]]
pruebas. No estoy sugiriendo eso =
y ==
son intercambiables en todas partes en bash.
Por ejemplo, obviamente no puede hacer una asignación variable con ==
, como var=="foo"
(bueno, técnicamente puede hacer esto, pero el valor de var
será "=foo"
, porque Bash no está viendo un ==
operador aquí, está viendo un =
operador (asignación), seguido de el valor literal ="foo"
, que simplemente se convierte"=foo"
).
También, aunque =
y ==
son intercambiables, usted debe tener en cuenta que la forma en esas pruebas de trabajo no depende de si se está usando en el interior [ ]
o [[ ]]
, y también de si o no los operandos se citan. Puede leer más sobre eso en la Guía avanzada de secuencias de comandos Bash: 7.3 Otros operadores de comparación (desplácese hacia abajo hasta la discusión de =
y ==
).
true
yfalse
en el contexto de la mayoría de los fragmentos a continuación, son solo cadenas simples, no elbash built-ins
!!! Lea la respuesta de Mike Holt a continuación. (Este es un ejemplo en el que una respuesta muy votada y aceptada es confusa en mi humilde opinión y oculta el contenido perspicaz en respuestas menos votadas)