¿Cuál es el propósito de "&&" en un comando de shell?

Respuestas:

399

&&le permite hacer algo en función de si el comando anterior se completó correctamente, es por eso que tiende a verlo encadenado do_something && do_something_else_that_depended_on_something.

girasquid
fuente
391

Además, también tiene ||cuál es el lógico o, y también ;cuál es solo un separador al que no le importa lo que sucedió antes con el comando.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Algunos detalles sobre esto se pueden encontrar aquí Listas de comandos en el Manual Bash.

plundra
fuente
55
Quizás te gustaría agregar false && echo "Will not be printed".
MTSan
112

línea de comandos: ¿para qué sirve &&?

Concha, cuando veas

$ command one && command two

la intención es ejecutar el comando que sigue al &&único si el primer comando es exitoso. Esto es idiomático de los proyectiles Posix, y no solo se encuentra en Bash.

Tiene la intención de evitar la ejecución del segundo proceso si el primero falla.

Puede notar que he usado la palabra "intención", eso es por una buena razón. No todos los programas tienen el mismo comportamiento, por lo que para que esto funcione, debe comprender lo que el programa considera un "error" y cómo lo maneja leyendo la documentación y, si es necesario, el código fuente.

Su shell considera un valor de retorno de 0 para verdadero, otros números positivos para falso

Los programas devuelven una señal al salir. Deberían devolver 0 si salen con éxito, o mayor que cero si no lo hacen. Esto permite una cantidad limitada de comunicación entre procesos.

Se &&hace referencia a esto como AND_IFen la gramática de shell posix , que forma parte de una and_orlista de comandos, que también incluye el ||cual es OR_IFcon una semántica similar.

Símbolos gramaticales, citados de la documentación:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

Y la Gramática (también citada de la documentación), que muestra que cualquier número de AND_IFs ( &&) y / o OR_IFs ( ||) se pueden unir (como and_orse define de forma recursiva):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Ambos operadores tienen la misma precedencia y se evalúan de izquierda a derecha (se dejan asociativos). Como dicen los documentos:

Una AND-ORlista es una secuencia de una o más tuberías separadas por los operadores "&&"y "||".

Una lista es una secuencia de uno o más y-OR listas separadas por los operadores ';'y '&'y opcionalmente terminado con ';', '&'o.

Los operadores "&&"y "||"tendrán la misma precedencia y se evaluarán con asociatividad izquierda. Por ejemplo, los dos comandos siguientes escriben únicamente barra en la salida estándar:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. En el primer caso, el falso es un comando que sale con el estado de 1

    $ false
    $ echo $?
    1

    lo que significa echo fooque no se ejecuta (es decir, cortocircuito echo foo). Entonces echo barse ejecuta el comando .

  2. En el segundo caso, salidas verdaderas con un código de 0

    $ true
    $ echo $?
    0

    y por echo foolo tanto no se ejecuta, luego echo barse ejecuta.

Aaron Hall
fuente
31

Un uso bastante común para '&&' es compilar software con autotools. Por ejemplo:

./configure --prefix=/usr && make && sudo make install

Básicamente, si la configuración tiene éxito, make se ejecuta para compilar, y si eso tiene éxito, make se ejecuta como root para instalar el programa. Lo uso cuando estoy casi seguro de que las cosas funcionarán, y me permite hacer otras cosas importantes como mirar stackoverflow y no 'monitorear' el progreso.

A veces me dejo llevar ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Hago esto cuando, por ejemplo, hago un linux desde cero.

Nigel Atkinson
fuente
2
Bueno en REPL, pero para los scripts preferiría set -o errexitpara Bash.
Franklin Yu
19

&&cadenas de comandos juntos. Los comandos sucesivos solo se ejecutan si los anteriores tienen éxito.

Del mismo modo, ||permitirá que el comando sucesivo se ejecute si falla el precedente.

Ver Programación de Bash Shell .

Dean Burge
fuente
8

Mira el ejemplo:

mkdir test && echo "Something" > test/file

Shell intentará crear un directorio testy luego, solo si fue exitoso , intentará crear un archivo dentro de él.

Por lo tanto, puede interrumpir una secuencia de pasos si uno de ellos falla.

alno
fuente
8

Es ejecutar una segunda declaración si la primera termina exitosamente. Como una declaración if:

 if (1 == 1 && 2 == 2)
  echo "test;"

Sus primeros intentos si 1 == 1, si eso es cierto, comprueba si 2 == 2

Mella
fuente
1
¿Podría alguien explicar por qué esto fue rechazado por los usuarios que se toparon con la pregunta?
user3243242
1
@ user3243242 no está mal, solo es un mal ejemplo para ilustrar el uso de&&
dan
Es una gran idea de cómo iffuncionan las pruebas en bash. Nunca lo pensé como una cadena de comandos de comparación, rompiendo cuando alguno de ellos fallaba. Así que tienes mi
voto a favor
1
La consecuencia es que puede obtener el comportamiento opuesto al usar ||, para encadenar comandos hasta que uno de ellos tenga éxito: eei || leu || uie || echo prout3 || echo "never executed"
PiRK
7

command_1 && command_2: ejecuta command_2 solo cuando command_1 se ejecuta con éxito.

command_1 || command_2: ejecuta command_2 solo cuando command_1 no se ejecuta correctamente.

Se siente similar a cómo se ejecuta una condición 'si' en un lenguaje de programación convencional, como, en la if (condition_1 && condition_2){...}condición_2 se omitirá si la condición_1 es falsey en la if (condition_1 || condition_2){...}condición_2 se omitirá si la condición_1 es true. Mira, es el mismo truco que usas para codificar :)

Xiaonin Li
fuente
No sé a qué te refieres con "exactamente lo contrario", pero $ echo '1' || echo '2' imprime solo '1'. y $ wrong_command || echo '2' imprime un mensaje de error y '2' en la siguiente línea. ¿Podría explicar un poco más sobre qué cree que está mal?
Xiaonin Li
ho tio, ayer estaba muy cansado. lo siento, solo fui yo: / Necesito que edites algo en tu respuesta si quieres que vote a favor (para hacer tu respuesta 0, ahora stackoverflow pide editar, así que no puedo)
Arount
@Arount, está bien, no te preocupes. Así que acabo de enviar una edición. entonces, ¿puedes eliminar el voto negativo ahora?
Xiaonin Li
Sí, una vez más, lo siento, de verdad
arount
0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Cuando el programa verifica si el comando, el programa crea un número llamado código de salida, si ambas condiciones son verdaderas, el código de salida es cero (0), de lo contrario, el código de salida es un número positivo. solo cuando se visualiza Equal si el código de salida se genera cero (0), eso significa que ambas condiciones son verdaderas.

Amin
fuente
Bienvenido a stackoverflow. Asegúrese de que su fragmento de código funcione antes de publicar aquí. Tienes que corregirloif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu
1
Gracias @ZhengQu por tu comando, ya estaba hecho.
Amin