Killing subprocessos após o script ter terminado ou ser morto

2

Digamos que eu tenha um script como o seguinte

#!/usr/bin/env zsh
./subscript.sh &
# do stuff
...
# do more stuff

Eu gostaria que o processo executando subscript.sh (e todos os processos iniciados por ele) fosse totalmente encerrado sempre que:

  1. O script acima sai
  2. O script acima é morto por qualquer motivo.

Como posso aplicar o acima? Isso é cuidado automaticamente pelo shell?

    
por Amelio Vazquez-Reina 16.06.2014 / 20:43

2 respostas

2

O shell definitivamente não matará espontaneamente seus subprocessos - afinal, um trabalho em segundo plano deve ser executado em segundo plano e não se importar com a vida de seu pai. (Em alguns casos, um shell interativo mata seus subprocessos quando sai - o que nem sempre é desejável, portanto nohup . )

Você pode fazer com que o script de shell mate seus trabalhos em segundo plano quando ele sair ou for eliminado por um sinal acessível. Registre os IDs do processo dos jobs e mate-os de uma armadilha. Observe que isso apenas mata as tarefas (como no processo original iniciado em segundo plano), não seus subprocessos.

jobs=()
trap '((#jobs == 0)) || kill $jobs' EXIT HUP TERM INT
…
subscript1 & jobs+=($!)
subscript2 & jobs+=($!)
…

Se você quer matar todos os processos e seus subprocessos, mais planejamento está em ordem. Um método é organizar todos os processos para que um arquivo único seja aberto. Para matar todos eles, mate todos os processos que possuem este arquivo aberto. Um subprocesso pode escapar fechando o arquivo.

#!/bin/sh
lock_file=$(mktemp)
exec 3<"$lock_file"
your_script
status=$?
exec 3<&-
fuser -k "$lock_file"
exit $status
    
por 17.06.2014 / 02:44
0

Você poderia interceptar EXIT e enviar um sinal para o grupo de processos do script.

no Linux

trap 'kill -SIGTERM 0' EXIT

no FreeBSD

trap 'kill -15 -$$' EXIT

SIGKILL é o único sinal em que isso não funcionaria, pois o script é morto incondicionalmente.

    
por 17.06.2014 / 01:16