Cuál es mejor: usar; o && para ejecutar múltiples comandos en una línea?

428

En los tutoriales y procedimientos a menudo veo comandos combinados. Por ejemplo,

sudo apt-get update && sudo apt-get install pyrenamer

Parece que hay cuatro conectores posibles: &, &&, ||y ;. Aunque el & conector es claro para mí (envía un proceso a un segundo plano y deja el terminal disponible), no está claro cuál es la diferencia entre &&y ;. Y no lo supe ||hasta el comentario de Kaya.

Las siguientes preguntas tratan la diferencia entre los dos conectores, pero lo hacen principalmente en los comentarios:

Aquí hay una serie de preguntas relacionadas:

  1. ¿Cuál es la diferencia entre ;y &&?
  2. ¿Cuándo deberías usarlos respectivamente? Sería bueno ver algunos casos de uso: si quiero ejecutar un comando y después de que apague mi computadora, ¿qué conector debo elegir?
  3. ¿Cuáles son sus ventajas y peligros ? Robie Basak menciona en un comentario a esta respuesta que un comando como cd /somewhere_else; rm -Rf *puede tener consecuencias destructivas si el primer elemento en la cadena de comandos falla, por ejemplo.
  4. Si es relevante, ¿de dónde vienen?
don.joey
fuente
77
Hay otro conector que quizás no haya encontrado: ||es el mismo que &&excepto que solo ejecuta el segundo comando si el primero salió con un estado distinto de cero (sin éxito).
Kaya
44
También tenga en cuenta que ejecutar su script con set -edetendrá el script en caso de falla como si todos los comandos estuvieran conectados &&.
choroba
stackoverflow.com/questions/3573742/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
3
Nadie respondió Qn 4 ... sospecho que el comportamiento de && y || fue inspirado por el lenguaje de programación C. En el caso de (x && y), si x se evalúa como falso, toda la expresión debe ser falsa para que un compilador pueda optimizar la evaluación de y, en caso de que sea costoso. Los estándares modernos de C y C ++ realmente requieren esta optimización, por lo que los programas pueden asumir con seguridad que y no será evaluado si x es falso. Por ejemplo, (ptr && ptr-> days> 31) no se bloqueará incluso si ptr es nulo. También en C, las declaraciones terminan con; independientemente de si hay otra declaración en la misma línea o no.
Kevin

Respuestas:

773

Cheatsheet:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.
Jack
fuente
19
Y, por supuesto A & B &,: ejecutar A en segundo plano, luego ejecutar B en segundo plano (independientemente del éxito) y devolver el control al shell. Esto a menudo funciona casi igual que ejecutar ambos procesos al mismo tiempo.
Expiación limitada del
44
¿es posible decir: ejecutar a en segundo plano, seguido de b en segundo plano solo si a funcionó? (Supongo que &&&?)
user230910
15
@ user230910: eso sería (A && B) &.
Leftaroundabout
55
¿Puede hacer referencia a un documento autorizado para esto?
Jaime Hablutzel
@Jack Cuando se ejecuta desde Cronjob, no sigue esta regla, ¿alguna idea de por qué? Para un archivo de Python
CodeGuru
77

&&solo ejecuta el segundo comando si el primero salió con el estado 0 (fue exitoso). ;ejecuta ambos comandos, incluso si el primero sale con un estado distinto de cero.

Su ejemplo con &&se puede parafrasear de manera equivalente como

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi
choroba
fuente
Gracias. He actualizado la pregunta para asegurarme de que las diferentes preguntas secundarias sean fácilmente distinguibles.
don.joey
55
@Private: debe usarlo ;si el segundo comando no necesita el anterior para tener éxito.
choroba
31

El uso ;ejecutará los comandos independientemente de si el primer comando es exitoso o no.

usando el &&segundo comando de ejecución solo cuando el primer comando se ejecutó con éxito (estado 0).

Ambos se usan en diferentes perspectivas. Como para un proceso más largo, digamos que para una instalación necesita compilarlo e instalarlo. que debiera make && make install. Por lo tanto, la instalación se ejecutará solo si tiene makeéxito.

Entonces, para los comandos dependientes, debe usar &&

Wring bash, o comandos con comandos independientes usan ;

Entonces, si desea apagar la computadora, incluso el primer trabajo falló ;, pero si desea el éxito completo del primer trabajo, inicie el uso de apagado&&

Nosotros somos
fuente
14

a ; bejecutará b independientemente del estado de salida de a. a && bejecutará b solo si a tuvo éxito.

Esto es necesario y suficiente para responder a las primeras 3 preguntas. En particular, el 2 es demasiado amplio y no se le puede dar "una" respuesta definitiva: su mejor opción es decidir caso por caso.

En cuanto a la cuarta pregunta: son la sintaxis de Bash .

No hay peligro intrínseco en el uso tampoco. Nuevamente, la definición anterior es suficiente. Implica que escribirá &&cuando btenga efectos ano deseados si no tiene éxito. No hay necesidad de más reglas o explicaciones, en mi humilde opinión.

ignis
fuente
1

UNA; B # Ejecutar A y luego B, independientemente del éxito de A

A && B # Ejecuta B si y solo si A tuvo éxito

A || B # Ejecuta B si y solo si A falla

A & # Ejecutar A en segundo plano.

Una muy buena regla de oro. Agregaría que, en algunos casos, usar estos comandos en una subshell tiene sentido cuando queremos considerarlos como una sola unidad o no queremos unir algunos resultados de operaciones con la shell actual.

Ejemplos:

-concatenar la salida de dos comandos:

(ls foo; ls bar) > single-result.txt

-entrando en un directorio y ejecutando un comando desde allí sin cambiar el directorio actual del shell:

(cd target-directory && jar -xf ../my-jar)
davidxxx
fuente