He estado aprendiendo bash esta semana y me encontré con un problema.
#!/bin/sh
if [ false ]; then
echo "True"
else
echo "False"
fi
Esto siempre dará como resultado True aunque la condición parezca indicar lo contrario. Si elimino los corchetes []
, funciona, pero no entiendo por qué.
bash
conditional-operator
tenmiles
fuente
fuente
#!/bin/sh
no es un script bash, es un script POSIX sh. Incluso si bash proporciona el intérprete de POSIX sh en su sistema, desactiva un montón de extensiones. Si desea escribir scripts de bash, use#!/bin/bash
o su equivalente apropiado localmente (#!/usr/bin/env bash
para usar el primer intérprete de bash en PATH).[[ false ]]
también afecta .Respuestas:
Está ejecutando el comando
[
(aliastest
) con el argumento "falso", no está ejecutando el comandofalse
. Como "falso" es una cadena no vacía, eltest
comando siempre tiene éxito. Para ejecutar realmente el comando, suelte el[
comando.fuente
bash
no tiene ningún tipo de datos booleanos, por lo que no hay palabras clave que representen verdadero y falso. Laif
declaración simplemente verifica si el comando que le das tiene éxito o falla. Eltest
comando toma una expresión y tiene éxito si la expresión es verdadera; una cadena no vacía es una expresión que se evalúa como verdadera, al igual que en la mayoría de los otros lenguajes de programación.false
Es un comando que siempre falla. (Por analogía,true
es un comando que siempre tiene éxito.)if [[ false ]];
devuelve cierto también. Como lo haceif [[ 0 ]];
. Yif [[ /usr/bin/false ]];
tampoco se saltea el bloque. ¿Cómo puede falso o 0 evaluar a distinto de cero? Maldición, esto es frustrante. Si es importante, OS X 10.8; Bash 3.false
con una constante booleana o0
un literal entero; ambos son solo cadenas ordinarias.[[ x ]]
es equivalente a[[ -n x ]]
cualquier cadenax
que no comience con un guión.bash
no tiene ningún constantes booleanas en cualquier contexto. Las cadenas que parecen enteros se tratan como tales dentro(( ... ))
o con operadores como-eq
o-lt
dentro[[ ... ]]
.if $predicate
se puede abusar fácilmente para ejecutar código hostil de una manera queif [[ $predicate ]]
no se puede.Una cartilla booleana rápida para Bash
La
if
afirmación adquiere un comando como argumento (como lo hacen&&
,||
etc.). El código de resultado entero del comando se interpreta como booleano (0 / nulo = verdadero, 1 / más = falso).La
test
declaración toma operadores y operandos como argumentos y devuelve un código de resultado en el mismo formato queif
. Es un alias de latest
declaración[
, que a menudo se usaif
para realizar comparaciones más complejas.Las declaraciones
true
yfalse
no hacen nada y devuelven un código de resultado (0 y 1, respectivamente). Por lo tanto, pueden usarse como literales booleanos en Bash. Pero si coloca las declaraciones en un lugar donde se interpretan como cadenas, se encontrará con problemas. En tu caso:Entonces:
Esto es similar a hacer algo así como
echo '$foo'
frenteecho "$foo"
.Cuando se usa la
test
declaración, el resultado depende de los operadores utilizados.En resumen , si solo desea probar algo como pasar / fallar (también conocido como "verdadero" / "falso"), entonces pase un comando a su declaración
if
o&&
etc., sin corchetes. Para comparaciones complejas, use corchetes con los operadores adecuados.Y sí, soy consciente de que no hay tal cosa como un tipo booleano nativo en Bash, y que
if
e[
ytrue
son técnicamente "comandos" y no "declaraciones"; Esta es solo una explicación muy básica y funcional.fuente
if (( $x )); then echo "Hello"; fi
muestra el mensaje parax=1
pero no parax=0
ox=
(indefinido).Descubrí que puedo hacer algo de lógica básica ejecutando algo como:
fuente
( $A && $B )
es una operación sorprendentemente ineficiente: genera un subproceso mediante una llamadafork()
, luego divide en cadena los contenidos de$A
para generar una lista de elementos (en este caso de tamaño uno) y evalúa cada elemento como un globo (en este caso uno que se evalúa a sí mismo), luego ejecuta el resultado como un comando (en este caso, un comando incorporado).true
y susfalse
cadenas provienen de otro lugar, existe el riesgo de que realmente puedan contener contenidos distintos detrue
ofalse
, y podría obtener un comportamiento inesperado que puede incluir la ejecución arbitraria de comandos.A=1; B=1
yif (( A && B ))
, tratándolos como numéricos, o[[ $A && $B ]]
, que trata una cadena vacía como falsa y una cadena no vacía como verdadera.El uso de verdadero / falso elimina el desorden de paréntesis ...
fuente
[[ "$0" =~ "bash" ]]
el guión funcione para mí.