La sintaxis de Shell depende en gran medida del contexto. Es decir, qué cosa en particular (como true
o false
) significa depende mucho de dónde ocurra. En tus ejemplos, false
tiene tres significados completamente diferentes:un comando, un valor de cadena y un nombre de variable (inexistente) que contiene un valor entero. Déjame repasar los ejemplos:
-
false
como comando:false; echo $? # prints "1" if false; then echo "yep"; else echo "nope"; fi # prints "nope"
Hay un comando llamado "false" (generalmente /usr/bin/false, o un bash incorporado que hace lo mismo) que realmente no hace nada excepto salir con un estado de falla. Como estado de salida, cero indica éxito (que es una especie de verdad) y distinto de cero indica falla (que es una especie de falso). Esto es lo opuesto a la convención más habitual cero=falso, distinto de cero=verdadero, pero para los estados de salida tiene más sentido.
-
false
como un valor de cadena no interpretado:if [[ false ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ true ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ wibble ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ "this is a string" ]]; then echo "yep"; else echo "nope"; fi # prints "yep" [[ false ]]; echo $? # prints "0" (=success) [ false ]; echo $? # prints "0" (=success) test false; echo $? # prints "0" (=success)
En todos estos casos, el comando
test
o su sinónimo[
o la expresión condicional bash[[ ]]
no obtuvo una expresión, solo una sola cadena, por lo que realizan una prueba muy simple:¿es una cadena de longitud distinta de cero? "verdadero", "falso", "wibble", etc. son todos de longitud distinta de cero, por lo que el comando/expresión es similar a la verdad, por lo tanto, exitoso. Comparar con:[[ "" ]]; echo $? # prints "1" (=failure), because the string is zero-length [[ ]]; echo $? # prints "1" (=failure), because there isn't even a string [ ]; echo $? # same
Tenga en cuenta que
test
y[
son comandos normales, y "falso" (y "wibble", etc.) es solo un argumento.[[ ]]
es un poco de sintaxis bash que se puede usar en lugar de un comando. Sus argumentos/contenidos se analizan de manera diferente a los nombres de los comandos. -
false
como posible nombre de variable que podría contener un número entero:if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # prints "equal"
Este es un poco más extraño y depende de los detalles de cómo
[[ ]]
de bash Pruebas de igualdad numérica. Tenga en cuenta que en[[ ]]
(y[ ]
ytest
expresiones),-eq
pruebas de igualdad numérica, y=
Pruebas de igualdad de cadenas. Entonces, por ejemplo,[[ 01 -eq 1 ]]
(porque 1 y 01 son numéricamente iguales) es cierto, pero[[ 01 = 1 ]]
es falso (porque no son la misma cadena). En el caso de[[ false -eq true ]]
, "verdadero" y "falso" no son valores enteros, por lo que bash intenta convertirlos en enteros tratándolos como nombres de variables (y esperando que las variables contengan valores enteros). De hecho, ninguno se define como una variable, por lo que ambos se evalúan como una cadena vacía, que puede interpretarse como el número entero 0. Observe:if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # prints "equal" if [[ false -eq 0 ]]; then echo "equal"; else echo "nope"; fi # prints "equal" false=5 if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # now prints "nope"
Tenga en cuenta que definir
false
como variable no tiene efecto sobre sus otros usos; cuando se usa como un comando, seguirá saliendo con el estado 1, y cuando se use como una cadena, seguirá siendo "falso" (no "5").