¿Existe alguna diferencia entre `;` y `&&` y `|`?

¿Existe alguna diferencia entre `;` y `&&` y `|`?

Cuando desee ejecutar varios comandos ;, puede utilizar &&y|

Así: killall Finder; killall SystemUIServer, cd ~/Desktop/ && rm CachesO: man grep | man catpor ejemplo.

Pero, ¿hay alguna diferencia |entre ;y &&? Si es así, ¿cuál es la diferencia?

Respuesta1

  • ;: los comandos separados por a ; se ejecutan secuencialmente. El shell espera a que cada comando finalice por turno.

  • &&: el comando posterior &&se ejecuta si, y solo si, el comando anterior &&devuelve un estado de salida de cero. Puedes considerarlo como ANDun operador.

  • |: un tubo. En expresión, command1 | command2la salida estándar del comando1 está conectada a través de una tubería a la entrada estándar del comando2.

Existen más operadores de control similares, vale la pena mencionar:

  • ||: el comando posterior ||se ejecuta si, y solo si, el comando anterior ||devuelve un estado de salida distinto de cero. Puedes considerarlo como ORun operador. Tenga en cuenta que |y ||son animales completamente diferentes.

  • &: el shell ejecuta el comando terminado en &en segundo plano, no espera a que finalice el comando e inmediatamente devuelve el código de salida 0. Una vez más, &no tiene nada que ver con &&.

  • |&: una abreviatura de, 2>&1 |es decir, que tanto la salida estándar como el error estándar del comando1 están conectados a la entrada estándar del comando2 a través de la tubería.

Además, si lo usa zsh, también puede iniciar el comando con &|o &!. En este caso, el trabajo se rechaza inmediatamente y después del inicio no tiene lugar en la tabla de trabajos.

Respuesta2

Considere dos comandos Ay B. Cuando escribes

A | B

Ay Bse ejecutan en paralelo, y la salida estándar de Ase envía como entrada estándar de B.

Cuando escribes

A; B

Ase ejecuta, luego Bse ejecuta (a menos que set -ese haya utilizado y Afinalice con un estado de salida distinto de cero, en cuyo caso el shell termina justo después de A).

Cuando escribes

A && B

Ase ejecuta, luego Bse ejecuta solo si Aha terminado exitosamente (estado de salida cero). Esta forma puede ser más segura que la anterior, por ejemplo con

cd some_dir && rm file*

Se &&asegura de que se eliminen los archivos correctos, es decir, los archivos se eliminan sólo si lo cdha logrado.

Respuesta3

Las otras respuestas ya explican |y , por lo que agregaré algo adicional que no haya solicitado &&explícitamente :.;||

A || B

Ase ejecuta y luego Bsolo se ejecuta si Afalla. Esto es útil para reaccionar ante condiciones de error:

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

( 2>/dev/nullEs necesario ocultar el mensaje de error rm).

Respuesta4

Nadie parece explicar por qué usarías cada uno, dados tus ejemplos reales. Lo intentaré:

killall Finder; killall SystemUIServer

Un comando como este killallpuede tardar algún tiempo en ejecutarse. Al usar el punto y coma, puedes dar ambos comandos a la vez y luego hacer otra cosa mientras esperas. De esa manera no tendrás que esperar dos veces (una por cada comando).

cd ~/Desktop/ && rm Caches

Quiere eliminar el directorio ~/Desktop/Cachesy terminar en el directorio ~/Desktop. Lo que no desea hacer es eliminar los cachés del directorio del directorio actual (antes de cambiarlo). Por lo tanto, debe &&verificar que el cambio de directorio se haya realizado correctamente antes de ejecutar el comando de eliminación.

man grep | man cat

Esto no tiene ningún sentido para mí. El mancomando no procesa la entrada, por lo que canalizarle cosas no hará nada. Quizás quisiste decir

man grep || man cat

Eso intentaría encontrar la página de manual de grepy luego, si no podía, mostraría la página de manual de cat. O posiblemente quisiste decir

man grep | cat

Eso se usaría catpara mostrar la página de manual en lugar del buscapersonas (normalmente less). Redirige |la salida manal comando cat(que simplemente arroja todo a la pantalla). Esto puede ser útil en una GUI donde puede usar la barra de desplazamiento para avanzar y retroceder en el archivo en lugar de usar los comandos del teclado en less.

Nota: si desea saber qué ; && | ||hacer en los casos más generales, le sugiero que consulte la respuesta de Jimmij. Solo estoy tratando de explicar lo que sucede en los ejemplos de la pregunta.

información relacionada