Eu tenho um script bash simples que inicia dois servidores:
#!/bin/bash
(cd ./frontend && gulp serve) & (cd ./backend && gulp serve --verbose)
Se o segundo comando sair, parece que o primeiro comando continua em execução.
Como posso mudar isso para que, se um comando sair, o outro for finalizado?
Observe que não precisamos verificar os níveis de erro dos processos em segundo plano, apenas se eles saíram.
bash
shell-script
background-process
blah238
fonte
fonte
gulp ./fronend/serve && gulp ./backend/serve --verbose
?serve
é um argumento, não um arquivo, portanto, o diretório atual precisa ser definido.Respostas:
Isso inicia os dois processos, aguarda o primeiro que termina e depois mata o outro:
Como funciona
Começar:
Os dois comandos acima iniciam os dois processos em segundo plano.
Esperar
Isso aguarda o término do trabalho em segundo plano.
Por causa da
-n
opção, isso requer o bash 4.3 ou melhor.Mate
Isso mata qualquer trabalho para o qual o processo atual é o pai. Em outras palavras, isso mata qualquer processo em segundo plano que ainda esteja em execução.
Se o seu sistema não possuir
pkill
, tente substituir esta linha por:que também mata o grupo de processos atual .
Exemplo facilmente testável
Alterando o script, podemos testá-lo mesmo sem
gulp
instalado:O script acima pode ser executado como
bash script.sh 1 3
e o primeiro processo termina primeiro. Como alternativa, é possível executá-lo comobash script.sh 3 1
e o segundo processo será encerrado primeiro. Em ambos os casos, pode-se ver que isso funciona como desejado.fonte
bash
suporte a-n
opção para owait
comando. (2) Concordo 100% com a primeira frase - sua solução inicia dois processos, aguarda a conclusão do primeiro e depois mata o outro. Mas a pergunta diz: "... se um comando cometer erros , o outro será encerrado?" Acredito que sua solução não é o que o OP deseja. (3) Por que você mudou(…) &
para{ …; } &
? As&
forças da lista (comando de grupo) para ser executado em um subshell de qualquer maneira. IMHO, você adicionou personagens e possivelmente introduziu confusão (eu tive que olhar duas vezes para entender) sem nenhum benefício.pkill
não está disponível para mim, maskill 0
parece ter o mesmo efeito. Também atualizei meu ambiente Git for Windows e parece quewait -n
funciona agora, por isso estou aceitando esta resposta.kill
. a documentação no meu sistema não menciona. No entanto,kill 0
funciona de qualquer maneira. Boa descoberta!Isso é complicado. Aqui está o que eu inventei; pode ser possível simplificá-lo / racionalizá-lo:
while true; do sleep 42; done &
) que dorme / pausa para sempre. Se você tiver certeza de que seus dois comandos serão encerrados dentro de um certo período de tempo (por exemplo, uma hora), você pode alterar isso para um único sono que excederá esse valor (por exemplo,sleep 3600
). Você pode alterar a lógica a seguir para usar isso como um tempo limite; ou seja, mate os processos se eles ainda estiverem em execução depois de tanto tempo. (Observe que o script acima atualmente não faz isso.)./
paracd
.command & echo "$!" > somewhere; wait "$!"
é uma construção complicada que inicia um processo de forma assíncrona, captura seu PID e aguarda por ele; tornando-o como um processo em primeiro plano (síncrono). Mas isso acontece em uma(…)
lista que está em segundo plano na sua totalidade, portanto, osgulp
processos são executados de forma assíncrona.gulp
saída de qualquer um dos processos, grave seu status em um arquivo temporário e interrompa o processo de "suspensão permanente".sleep 1
para proteger contra uma condição de corrida em que o primeiro processo em segundo plano morre antes que o segundo tenha a chance de gravar seu PID no arquivo.gulp
processos, conforme indicado acima.fonte
Para completar, eis o que acabei usando:
Isso funciona para mim no Git for Windows 2.5.3 de 64 bits. As versões mais antigas podem não aceitar a
-n
opção ativadawait
.fonte
No meu sistema (Centos),
wait
não tem,-n
então eu fiz isso:Isso não espera "qualquer um", mas espera o primeiro. Mas ainda assim pode ajudar se você souber qual servidor será parado primeiro.
fonte
wait
tem a-n
opção ou não depende do shell você está usando, não a distribuição Linux.