Saindo de um script Bash quando um filho sudo sai

2

Estou tentando iniciar alguns subprogramas a partir de um script bash e depois esperar que qualquer um deles seja encerrado antes de sair do outro e sair do script.

CMD1PID=
CMD2PID=

exit_trap () {
    echo "exit trap: killing jobs..." 
    sudo kill $CMD1PID $CMD2PID
    exit
}

set -bm
trap exit_trap EXIT INT TERM

sudo cmd1 --args &
CMD1PID=$?

sudo cmd2 --args &
CMD2PID=$?

wait $CMD1PID $CMD2PID

(para referência, isso é GNU bash, version 4.2.37(1)-release (arm-unknown-linux-gnueabi) no Debian Weezy)

Infelizmente, isso não parece funcionar corretamente. Eu tentei várias variantes, como:

  • usando chaves ao redor dos comandos e explicitamente eliminando o processo de shell depois, ou seja, { cmd1 --args ; kill -USR1 $$ ; } & ou similar e, em seguida, trapping na USR1
  • usando kill 0 para eliminar os comandos ainda em execução na saída
  • trapping CHLD - isso tem a desvantagem de não poder sleep entre os comandos se eu precisar, o que eventualmente preciso fazer.

... mas os problemas que tenho a ver são:

  • Matar um dos comandos não faz com que o processo pai de Bash saia e / ou mate o outro comando
  • Matar o processo pai do Bash não faz com que ambos os comandos sejam eliminados

Eu suspeito que talvez minha exigência de usar o sudo esteja me atrapalhando, já que outras pessoas em outros scripts parecem estar tendo sorte com scripts similares. Existe uma boa maneira de fazer o que estou tentando fazer no bash?

    
por jldeon 31.10.2013 / 17:22

1 resposta

2

Você tem dois problemas: você precisa identificar quando uma das crianças interessantes é feita e você precisa matar todas elas.

O primeiro significa que você não pode usar o "wait" embutido, porque ele irá esperar por todos filhos (ou todos os listados, se houver), não para nenhum . Sua sugestão baseada em USR1 funciona bem para isso (e para EXIT).

O segundo é muito mais difícil: como você está usando o sudo, você não tem permissão para enviar um sinal para os processos; para enviar um sinal para um processo, o seu ID do usuário deve corresponder ou você deve ser root.

Você poderia tentar usar sinalização baseada em sistema de arquivos ou manipulador de arquivos ou algo assim, mas francamente, isso será muito mais compreensível e legível e sustentável em alguma outra linguagem de script (python, perl, o que for), e mesmo assim é muito complicado. Provavelmente, é melhor você executar o script inteiro sob o usuário de destino.

    
por 12.11.2013 / 02:46