Tengo un script bash simple que inicia dos servidores:
#!/bin/bash
(cd ./frontend && gulp serve) & (cd ./backend && gulp serve --verbose)
Si sale el segundo comando, parece que el primer comando continúa ejecutándose.
¿Cómo puedo cambiar esto para que si alguno de los comandos sale, el otro se termina?
Tenga en cuenta que no necesitamos verificar los niveles de error de los procesos en segundo plano, solo si han salido.
bash
shell-script
background-process
blah238
fuente
fuente
gulp ./fronend/serve && gulp ./backend/serve --verbose
?serve
es un argumento, no un archivo, por lo que debe establecerse el directorio actual.Respuestas:
Esto inicia ambos procesos, espera el primero que finaliza y luego mata al otro:
Cómo funciona
Comienzo:
Los dos comandos anteriores inician ambos procesos en segundo plano.
Espere
Esto espera a que finalice cualquiera de los trabajos en segundo plano.
Debido a la
-n
opción, esto requiere bash 4.3 o superior.Matar
Esto mata cualquier trabajo para el cual el proceso actual es el padre. En otras palabras, esto mata cualquier proceso en segundo plano que todavía se está ejecutando.
Si su sistema no tiene
pkill
, intente reemplazar esta línea con:que también mata al grupo de proceso actual .
Ejemplo fácilmente comprobable
Al cambiar el script, podemos probarlo incluso sin tener
gulp
instalado:El script anterior se puede ejecutar como
bash script.sh 1 3
y el primer proceso termina primero. Alternativamente, uno puede ejecutarlo comobash script.sh 3 1
y el segundo proceso terminará primero. En cualquier caso, se puede ver que esto funciona como se desea.fuente
bash
admiten la-n
opción delwait
comando. (2) Estoy de acuerdo al 100% con la primera oración: su solución inicia dos procesos, espera a que termine la primera y luego mata a la otra. Pero la pregunta dice: "... si alguno de los comandos falla , ¿el otro termina?" Creo que su solución no es lo que quiere el OP. (3) ¿Por qué cambió(…) &
a{ …; } &
? De&
todos modos, obliga a la lista (comando de grupo) a ejecutarse en una subshell. En mi humilde opinión, ha agregado caracteres y posiblemente introdujo confusión (tuve que mirarlo dos veces para comprenderlo) sin ningún beneficio.pkill
no está disponible para mí, perokill 0
parece tener el mismo efecto. También actualicé mi entorno Git para Windows y parece quewait -n
funciona ahora, así que acepto esta respuesta.kill
. la documentación en mi sistema no lo menciona. Sin embargo,kill 0
funciona de todos modos. ¡Buen descubrimiento!Esto es complicado Esto es lo que ideé; puede ser posible simplificarlo / simplificarlo:
while true; do sleep 42; done &
) que duerme / pausa para siempre. Si está seguro de que sus dos comandos terminarán dentro de un cierto período de tiempo (p. Ej., Una hora), puede cambiar esto a una sola suspensión que excederá eso (psleep 3600
. Ej., ). Luego puede cambiar la siguiente lógica para usar esto como un tiempo de espera; es decir, elimine los procesos si todavía se están ejecutando después de tanto tiempo. (Tenga en cuenta que el script anterior actualmente no hace eso)../
paracd
.command & echo "$!" > somewhere; wait "$!"
es una construcción complicada que inicia un proceso de forma asincrónica, captura su PID y luego lo espera; convirtiéndolo en una especie de proceso en primer plano (sincrónico). Pero esto sucede dentro de una(…)
lista que está en segundo plano en su totalidad, por lo que losgulp
procesos se ejecutan de forma asincrónica.gulp
procesos salga, escriba su estado en un archivo temporal y elimine el proceso de "suspensión permanente".sleep 1
para protegerse contra una condición de carrera donde el primer proceso en segundo plano muere antes de que el segundo tenga la oportunidad de escribir su PID en el archivo.gulp
procesos sale, como se indicó anteriormente.fuente
Para completar, esto es lo que terminé usando:
Esto funciona para mí en Git para Windows 2.5.3 de 64 bits. Las versiones anteriores pueden no aceptar la
-n
opción enwait
.fuente
En mi sistema (Centos),
wait
no tiene,-n
así que hice esto:Esto no espera "tampoco", sino que espera el primero. Pero aún así puede ayudar si sabe qué servidor se detendrá primero.
fuente
wait
tiene la-n
opción o no, depende del shell que esté utilizando, no de la distribución de Linux.