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}
.)