OBJETIVO DO SCRIPT: o script é invocado como ./script.sh cmd1 cmd2 ... cmdn
. Ele deve executar em segundo plano todos os comandos passados como argumentos da linha de comando e verificar quando todos terminaram sua execução.
Além disso, se o sinal SIGTERM for enviado para o script, ele deve matar todos os processos acima mencionados ( cmd1 ... cmdn
) e depois se matar.
PROBLEMA: Tudo parece funcionar, exceto a autoterminação e não consigo entender por quê.
Eu tentei usar kill $$
, mas em tempo de execução eu recebo segmentation fault
.
Eu estava pensando que o problema estava relacionado ao fato de que o comando kill
está dentro de uma função mas, por outro lado, se eu comentar kill $$
e eu deixar o comando kill ${PIDAR[*]}
, o último trabalho.
Alguém poderia me explicar o que estou perdendo?
#!/bin/bash
# signal handler
killemall () {
echo $$
kill ${PIDAR[*]}
kill $$ # implicated line
}
PIDAR=() # pid array
STAR=() # process state array
# execute processes in bg and save their pid
for i in "$@" ; do
$i &
PIDAR+=($!)
done
trap 'killemall' SIGTERM
terminated=1 # flag to indicate when all processes are terminated
while sleep 1 && [ $terminated -eq 1 ]; do
for (( i=0; i<${#PIDAR[*]}; i++ )); do
STAR[$i]=$(ps hp ${PIDAR[$i]} | awk '{ print $3 }')
if [ -z ${STAR[$i]} ]; then
terminated=0
else terminated=1
fi
echo "Process state ${PIDAR[$i]}:${STAR[$i]}" | tee -a logg
done
done
echo "All processes are terminated"
Obrigado
SOLUÇÃO: como user18197 apontou, o problema está chamando kill $$
.
De fato, como a página kill
man reporta:
The default signal for kill is TERM
Em seguida, a cada invocação de kill $$
, o script chamava o manipulador killemall
, que por sua vez estava invocando novamente kill $$
e assim por diante de forma recursiva.
Para evitar esse comportamento, podemos remover SIGTERM
signal. Como help trap
relatórios:
If ARG is absent (and a single SIGNAL_SPEC
is supplied) or '-', each specified signal is reset to its original
value.
O novo corpo da função é:
killemall () {
echo $$
trap - SIGTERM
kill ${PIDAR[@]}
kill $$
}