
Cuando desee ejecutar varios comandos ;
, puede utilizar &&
y|
Así: killall Finder; killall SystemUIServer
, cd ~/Desktop/ && rm Caches
O: man grep | man cat
por 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 comoAND
un operador.|
: un tubo. En expresión,command1 | command2
la 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 comoOR
un 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 A
y B
. Cuando escribes
A | B
A
y B
se ejecutan en paralelo, y la salida estándar de A
se envía como entrada estándar de B
.
Cuando escribes
A; B
A
se ejecuta, luego B
se ejecuta (a menos que set -e
se haya utilizado y A
finalice con un estado de salida distinto de cero, en cuyo caso el shell termina justo después de A
).
Cuando escribes
A && B
A
se ejecuta, luego B
se ejecuta solo si A
ha 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 cd
ha logrado.
Respuesta3
Las otras respuestas ya explican |
y , por lo que agregaré algo adicional que no haya solicitado &&
explícitamente :.;
||
A || B
A
se ejecuta y luego B
solo se ejecuta si A
falla. 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/null
Es 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 killall
puede 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/Caches
y 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 man
comando 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 grep
y 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 cat
para mostrar la página de manual en lugar del buscapersonas (normalmente less
). Redirige |
la salida man
al 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.