Veo el mismo comportamiento para el ciclo a continuación que el ciclo con while [ 1 ]
. ¿Por qué es así?
while [ 0 ]; do
echo "hello"
done
Veo el mismo comportamiento para el ciclo a continuación que el ciclo con while [ 1 ]
. ¿Por qué es así?
while [ 0 ]; do
echo "hello"
done
Respuestas:
Los corchetes individuales en el shell son sinónimo de test
(ya sea el comando separado o el shell incorporado), por lo que [ 0 ]
significa lo mismo que test 0
. test
es para hacer comparaciones y probar los atributos de los archivos, como puede leer en su página de manual. Cuando no se le da una expresión que se parezca a una comparación, prueba de archivo o una de las otras operaciones que puede hacer, en su lugar probará si el argumento está presente y es una cadena no vacía. Ninguna 0
o 1
son entradas realmente apropiadas para la prueba, y como prueba de cadenas no vacías simplemente tiene éxito y su bucle while se repite para siempre.
Quizás quieras probar en su lugar
while false; do
echo "hello"
done
posiblemente reemplazando false
con true
. O tal vez lo que quieres es usar (( ))
:
while (( 0 )); do
echo "hello"
done
Que se comportará como la mayoría de los idiomas, donde 0 significa falla / falso y 1 significa éxito / verdadero.
0
y 1
no son cadenas vacías. Los nuevos programadores de shell a menudo escriben en if [ 1=2 ]
lugar de if [ 1 = 2 ]
y se preguntan por qué el primero siempre es cierto. Es cierto porque es un argumento único y no es una cadena vacía.
El valor 0 aquí no actúa como una constante numérica, sino como una cadena de caracteres. Estas pruebas son todas equivalentes en su efecto de producir un estado de terminación exitoso:
[ A ]
[ "XYZ" ]
[ 0 ]
estos producen un estado de terminación fallido:
[ ]
[ "" ]
hay un argumento no en blanco, que se evalúa como verdadero lógico. Esto le permite hacer cosas como:
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
La variable UNDER_NUCLEAR_ATTACK
se establece en cualquier valor que no esté en blanco para indicar verdadero, o está desarmado o vacío para indicar falso.
Podemos aplicar el !
operador para invertir la lógica:
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
Para evaluar una condición numérica, debe usar operadores de prueba numéricos:
while [ $A -gt $B ] ; do ...
Si A
y B
contienen cadenas que parecen enteros decimales, se comparan como números, y si A
es mayor que B
, el bucle se ejecuta. Supongamos que UNDER_NUCLEAR_ATTACK
no es un booleano de tipo cadena que está en blanco o no en blanco, sino que es un booleano numérico que es 0
(falso) o algún otro valor (verdadero). En ese caso, escribiríamos la prueba así:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
Una construcción if / then prueba si el estado de salida de una lista de comandos es 0 (ya que 0 significa "éxito" según la convención de UNIX) y, de ser así, ejecuta uno o más comandos.
En resumen, está devolviendo un resultado de prueba de cero.
[
obtiene solo un argumento (excluyendo el ]
, por supuesto) sale con el estado cero si el argumento no está vacío, distinto de cero si lo está. Entonces, por ejemplo, [ 1 ]
también devolverá un código de salida de 0
.
El valor 0 se considera verdadero para el ciclo while, por lo tanto, la condición para el ciclo while es verdadero y, por lo tanto, es continuo para mostrar el ciclo infinito. El es verdadero si reemplazamos 0 con 1, ya que cualquier entero que escribamos entre la condición devolverá verdadero
[ ]
(sin argumento) y[ "" ]
(con un solo argumento vacío) no tienen éxito.