Eu li uma postagem sobre como lidar com SIGINT signal, mas ainda não entendi como para manipulá-lo adequadamente no código que será originado e usado por ambos os shells interativos e não interativos.
Vou dar um exemplo simplificado do meu roteiro e fazer perguntas para partes específicas.
Eu tenho um script com funções úteis que devem ser originadas e usadas em qualquer lugar.
/tmp/useful_functions.sh
#!/bin/bash
function example()
{
echo "Main script started"
# Make process run forever in the background.
( while sleep 1; do echo "Background script running"; done ) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
}
Permite usar a função exemplo em outro script.
/tmp/test.sh
#!/bin/bash
source /tmp/useful_functions.sh
example
Agora vamos executar /tmp/test.sh e pressionar Control-C enquanto a subshell está funcionando.
(subshell = $(sleep 10; echo "Subshell completed") )
Test 1
/tmp/test.sh , example , subshell e background foram finalizados.
O prompt aguardava novas entradas.
SIGINT foi enviada / manipulada / propagada entre processos? SIGINT deve ser enviado para todos os processos em primeiro plano e que o mais interno deve primeiro tratá-lo.) Permite usar a função exemplo diretamente no Bash interativo:
...$ source /tmp/useful_functions.sh
...$ example
e novamente pressione Control-C enquanto a subshell está funcionando.
(subshell = $(sleep 10; echo "Subshell completed") )
Test 2
example e subshell foram finalizados, mas o processo backgrounded permaneceu ativo.
O prompt aguardava novas entradas, embora a saída do processo backgrounded tenha sido impressa.
SIGINT enviada / manipulada / propagada entre processos? Mesmo que eu não entenda totalmente o comportamento de Test 1 , esse comportamento é desejado e eu queria realizar isso também com o Bash interativo.
A idéia era criar outra subcamada que envolvesse o processo em segundo plano e a subcamada existente e esperasse que a finalização desse novo processo levasse à finalização do processo em segundo plano e da subcamada existente.
/tmp/useful_functions.sh
#!/bin/bash
function example()
{
(
echo "Main script started"
# Make process run forever in the background.
( while sleep 1; do echo "Background script running"; done ) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
)
}
Test 1 repetidos
/tmp/test.sh , example , outer subshell , inner subshell e background foram encerrados.
O prompt aguardava novas entradas.
SIGINT enviada / manipulada / propagada entre processos? Test 2 repetidos
example , outer subshell , inner subshell e background foram finalizados.
O prompt aguardava novas entradas.
SIGINT enviada / manipulada / propagada entre processos? Neste ponto, percebi que, na verdade, preciso fazer algumas limpezas após o processo em segundo plano e que preciso prender SIGINT em algum lugar para lidar com isso.
Como não sei como SIGINT é tratado e propagado geralmente no Bash, fiz algumas suposições e encontrei uma solução que acho que funciona corretamente, mas não tenho certeza.
#!/bin/bash
function example()
{
(
echo "Main script started"
# Make process run forever in the background.
(
trap "echo Cleanup; trap - SIGINT; kill -s SIGINT ${$}" SIGINT
while sleep 1; do echo "Background script running"; done
) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
)
}
SIGINT ? ${$} está correto? ${$} em vez de ${BASHPID} .)