Como enviar um sinal de sinalização do script para o script?
Pergunta
Eu quero prender um sinal de envio de script-a.sh para script-b.sh, então no script-a.sh eu uso o comando:
(Envie SIGINT para Script-B.Sh)
matar -2 $ pid_script -b.sh
E no script-b.sh pego o sinal e chamo função limpa
armadilha 'limpa' 2
Não funciona, em vez disso, o script-b.sh é morto imediatamente sem executar o limpo !!
O que noto também é que, se eu quiser enviar SIGINT do terminal para qualquer script que o prenda, um ctrl-c
será pego corretamente, mas não se eu especificar o sinal através do comando kill -2 $pid_of_script
Qualquer idéia sobre a diferença entre os dois métodos para enviar o SIGINT (ctrl-c
Vs. kill -2 $pid_of_script
), e como posso enviar um sigint de um script para outro?
Solução
Consegui reproduzir o comportamento que você relata. Minha hipótese é que, uma vez que o script está em execução a partir de uma concha não interativa (como criança de um script) que SIGINT
, que é um sinal de teclado, é ignorado.
A partir de info bash
:
Os processos de fundo são aqueles cujo ID do grupo de processos difere do do terminal; Tais processos são imunes a sinais gerados pelo teclado.
Eu descobri que se você trap
e kill
usando outro sinal como SIGUSR1
funciona.
Informações adicionais de man bash
:
Os comandos não construídos executados pelo Bash têm manipuladores de sinal definidos para os valores herdados pelo shell de seus pais. Quando o controle do trabalho não está em vigor, os comandos assíncronos ignoram o SIGINT e o sigquit, além desses manipuladores herdados.
e
Se o Bash estiver aguardando a conclusão de um comando e receber um sinal para o qual uma armadilha foi definida, a armadilha não será executada até que o comando seja concluído.
e
Qualquer armadilha no Sigchld é executada para cada criança que sai.
Outras dicas
No script A: A função do traping será seguida, que chamará a função TRAP_MESG () no scripta.sh. Signal de matar (2/interrupção, 5/terminação-defasa). Tudo, você precisa fazer é obter o PID de um scriptb.sh de execução do processo/sessão assim que o scriptb.sh for chamado de scripta.sh (nohup ... & vai dar ou usar o comando ps)
trap_mesg ()
{
#...do something here for script B..
# i.e.
kill -2 PID_of_ScriptB.sh_running_process_session
sleep 10; #just in case, not reqd though.
#show using ps -eAf|grep "scriptB" ... if null means, scriptB is gone. user is happy now.
#...before actually exiting out...
#show script A is exiting out as ScriptB is dead already, time for scriptA now.
#...do something here..
}
#####################################
## Trap signals : INT, TERM. catch ##
#####################################
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script.
trap_call="";
trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15
##################################
Agora, no scriptb.sh, faça o mesmo/semelhante, mas apenas para o ScriptB Trap Job (como chamar Clean).
clean ()
{
echo "karoge seva to milega meva";
rm -fr /some/folder_file
}
trap_mesg ()
{
#...do something here JUST for script B trap message work..
# i.e.
clean;
#...do something here..
}
#####################################
## Trap signals : INT, TERM. catch ##
#####################################
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script.
trap_call="";
trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15
##################################
Dessa forma, você não precisa adquirir/ligar para scriptb.sh em scripta.sh como ". Scriptb.sh ...."