Parecen indicar a BASH que comience con otro comando después de los símbolos, pero ¿hay una diferencia clara?
Parecen indicar a BASH que comience con otro comando después de los símbolos, pero ¿hay una diferencia clara?
Respuestas:
Con esta linea:
command1 && command2
command2 se ejecutará si (y solo si) command1 devuelve el estado de salida cero, mientras que en esta línea:
command1 ; command2
Tanto el comando1 como el comando2 se ejecutarán independientemente. El punto y coma le permite escribir muchos comandos en una línea.
Puedes probar la diferencia por ti mismo:
ls /invalid/path && echo "hello!"
como / inválido / ruta no existe, ls no puede mostrarle el listado del directorio. Fallará con un mensaje de error: "ls: / invalid / path: No existe dicho archivo o directorio".
La segunda mitad del comando (echo "hola!") Nunca se ejecuta porque la primera mitad falló.
ls /invalid/path ; echo "hello!"
El mismo mensaje de error aparece como antes, pero esta vez, se ejecuta la segunda parte .
ls: / invalid / path: ¡No existe tal archivo o directorio
hola!
¿Por qué es útil esto?
Suponga que desea extraer un archivo llamado archive.tar.gz.
Puede usar el comando tar zxvf archive.tar.gz && rm archive.tar.gz
.
Si por alguna razón falla la extracción del archivo, ¡la segunda parte no se ejecuta! Puedes intentarlo de nuevo.
Si utiliza ; en la misma situación, el archivo se elimina y no puede volver a intentarlo.
&&
es AND
decir, el segundo comando solo se ejecutará si el primero devuelve verdadero (sin errores).
AND
ejecución, el segundo parámetro se vuelve irrelevante si el primero es igual false
y, por lo tanto, el código subyacente se optimiza para posponer la evaluación del segundo parámetro hasta que sepa cuál es el primero.
&&
es solo un operador binario, una función. Lo único "especial" es que es la notación infija (que es estándar para la mayoría de este tipo de operadores de todos modos) y la ejecución retrasada del segundo operando. Esa ejecución retrasada de hecho le da la capacidad de ser utilizado como algo que puede verse conceptualmente como una if
declaración en este contexto , pero eso no quita el hecho de que su uso original está dentro del condicional de una if
declaración real . El uso aquí realmente es más un "hack".
a && b || c = (a && b) || c
. Orden simple de evaluación. Realmente no hay misterio allí. Si las escribiera como sus funciones típicas, simplemente se vería así or(and(a, b), c)
. Esta lógica es la misma dentro de un if
condicional así como cuando se ingresa directamente en la línea de comando porque &&
y ||
son operadores , toman dos operandos y devuelven otro.
Actualización : agregué como script para resaltar algunas de las posibles trampas:
Porque nadie más ha mencionado "||", lo haré
Actualización 2 : algunas modificaciones importantes aquí
&& es como un "entonces" de una declaración "if" que responde a "true"
|| NO es como el "else" de una declaración "if" ..
|| es como un "entonces" de una declaración "if" que responde a "false"
Más específicamente, && prueba el $? valor de retorno de la anterior ejecutada más recientemente declaración y pasa el control al estado de cuenta o sub-shell inmediatamente después de la && ... sólo pasa el control si $? es verdad.
|| es similar, y a menudo se ve después de una declaración &&, pero prueba un valor de retorno falso ($?) de la declaración ejecutada más recientemente anterior ... ¡NOTA! , Nota Bene! ¡Tenga en cuenta bien! ... si la declaración anterior es una declaración && que se vuelve falsa cuando espera que sea verdadera, entonces || responderá a lo falso, por lo que mezclar ambos en la misma línea puede ser arriesgado
El punto principal que estoy tratando de hacer es en relación con un error que cometí. es decir:
## [[condición]] && A || B
is not no se comporta como un ternario de estilo C / C ++. es decir:
// (condición)? A: B
Consulte el script a continuación para ver ejemplos de resultados "inesperados" de "A"
La prueba básica y el && y el || la declaración debe estar en la misma línea ...
Ejecute este script para ver dónde pueden salir mal las cosas al usar && y ||
La declaración ejecutada más recientemente puede no ser la que espera.
[[condición]] && echo Hola || echo Goodbye .... es típicamente seguro,
porque un eco bien formado volverá verdadero.
pero ¿qué pasa con el acceso a un archivo que no sale?
#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo ======
((1==1)) && echo " ((1==1)) rc=$? ..&&.. condition is true" || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && echo " \$0 0 rc=$? ..&&.. condition is true" || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && echo " \$0 1 rc=$? ..&&.. condition is true" || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo ======
((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false"
$0 0 || echo " \$0 0 rc=$? ..||.. condition is true" && echo " \$0 0 rc=$? ..&&.. condition is false"
((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false"
$0 1 || echo " \$0 1 rc=$? ..||.. condition is true" && echo " \$0 1 rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
exit
tratar
falso && echo "hola"
y
falso echo "hola"
ver la diferencia
El comando (función, en el caso de un script) después &&
se ejecuta según el RETVAL del primer comando (función, en el caso de un script). Obliga al primer comando a devolver un valor de 0, si tiene éxito. Podemos verificar el valor de retorno para ejecutar más comandos.