¿Cómo encadeno los comandos en la consola?

23

En bash, a veces quiero ejecutar varios comandos en serie y no quiero esperar a que terminen antes de escribir los nuevos. Entonces hago algo como esto:

cmd1; cmd2; cmd3

Desafortunadamente, uno de los comandos puede fallar. En ese caso, me gustaría parar. ¿Hay una manera fácil de hacer esto, pero hacer que solo siga ejecutando los comandos si el comando anterior tenía un código de salida 0?

metáfora pitónica
fuente
Aquí hay una gran respuesta del Unix SE.
NonlinearFruit

Respuestas:

39

Usar &&operador,

cmd1 && cmd2 && cmd3

En shellscripting, &&y los ||operadores se modelan después de la implementación optimizada de operadores lógicos en C. &&significa operador AND, y ||significa OR. Unix está estrechamente relacionado con C, y en C, el segundo operando de operadores lógicos no se evalúa si el resultado ya se conoce del primer operando. Por ejemplo, "false && x"es falsepara cualquier x, por lo que no hay necesidad de evaluar x(especialmente si se xtrata de una llamada de función); igualmente para "true || x". Esto también se llama semántica de cortocircuito .

Y en Unix, es tradicional interpretar los valores de retorno de los comandos como valores de verdad de "finalización exitosa": el código de salida 0 significa true(éxito), no cero significa false(falla). Entonces, cuando el primer comando en cmd1 && cmd2retorna "false"(estado de salida distinto de cero, que indica falla), se conoce el estado del comando compuesto: falla. Entonces, la interpretación general de cmd1 && cmd2 puede ser: "ejecutar cmd1, Y ENTONCES, si no falla cmd2". Que es lo que básicamente quieres en tu pregunta.

De manera similar con OR: cmd1 || cmd2puede interpretarse como "ejecutar cmd1, O SI falla cmd2".


Protip: para cadenas más largas de &&, considere poner set -een su script. Básicamente cambia el punto ;y coma en &&, con un par de casos especiales.

ulidtko
fuente
1
+1 para explicar||
Alp
¿Puedes encadenar cualquiera que sea el estado del primer comando? (éxito o fracaso)
Hugo Trentesaux
@HugoTrentesaux ¿qué quiere decir? .. El / resultado el fracaso o el éxito A || Bes lo mismo que el [cortocircuitando] lógica AOB . A || Bes el éxito cuando Afue éxito o cuando Afue fracaso pero Bfue éxito ; y A || Bes fracaso cuando Aera fracaso y Bfue failure. Del mismo modo &&, sigue lógicamente AND.
ulidtko
En el contexto de shell, ¿cómo puedo ejecutar A y luego B sin importar si A falla o tiene éxito?
Hugo Trentesaux
1
@HugoTrentesaux, eso es lo que hace el regular normal ;(o nueva línea) por defecto. set -ese convertirá ;en &&, más o menos hablando. set +e[el valor predeterminado] se convierte A; Ben lo que usted dice: ejecutar A, luego no importa qué ejecute B.
ulidtko
13

"Encadenando Comandos y Agrupándolos"

ping 192.168.0.1 || { echo "ping not successful"; exit 1; }

pings, solo si no tiene éxito, ejecuta el grupo encadenado de comandos entre paréntesis.

Atención:

La lista debe terminarse con un ";".

¡Debe haber espacios en blanco entre paréntesis y los comandos agrupados!

y yo
fuente
6

Simplemente con el &&operador. Por ejemplo:

cmd1 && cmd2 && cmd3

Si uno de los comandos falla (devuelve un valor de salida distinto de 0), los otros comandos no se ejecutarán.

Wuffers
fuente