Na verdade, ele foi impresso, mas você precisa esperar 100 segundos para ver o resultado.
Você disse:
$./test.sh > output &
[4] 42624
Se você marcar ps aux
, receberá algo semelhante a:
xiaobai 42624 0.0 0.1 118788 5492 pts/3 S 04:07 0:00 /bin/bash
xiaobai 42626 0.0 0.0 108192 668 pts/3 S 04:07 0:00 sleep 100
Seu processo de script principal de / bin / bash, PID 42624 ainda está esperando pelo término do sleep 100. Mesmo o processo principal recebeu o sinal 1, ele tem que esperar sleep 100
terminar primeiro, depois é a vez dele executar sua tarefa, ou seja, echo "cleaning up!"
.
Você pode tornar o processo de suspensão um processo em segundo plano. Nesse caso, o processo de script pode executar echo "cleaning up!"
sem aguardar o sleep process
, se e somente se o processo do script não sair ainda.
Podemos provar que o script conceitual (por exemplo, está aguardando sleep
antes do sinal de identificador) por meio desse script:
function clean_up {
echo "cleaning up!"
}
echo 'starting!'
trap clean_up SIGHUP
sleep 5000 &
echo 1
sleep 20
echo 2
sleep 10
echo 3
Execute este script em ./test.sh > output
como de costume, depois use ps aux
para descobrir que /bin/bash
PID é 23311 e, em seguida, faça kill -1 23311
. Ao mesmo tempo cat output
para conhecer o estágio, ou seja, quando o script entrar em sleep 20
após o eco 1, envie kill -1 23311
, agora espere 2 sair, você notará que a "limpeza" foi impressa em conjunto antes de 2 Finalmente, é a vez de echo 3
e a saída do script.
$ cat output
starting!
1
cleaning up!
2
3
$
O experimento acima provou que o script recebe o sinal SIGHUP e executa o manipulador de sinal depois que todo o processo de foreground anterior é feito e, por sua vez, sem esperar o processo em segundo plano.
A história se torna interessante, com seu script original, e se você fizer kill -1 PID_of_sleep_100
?
Ele sairá de todos os processos sem impressão, porque o processo de suspensão não retorna SIGHUP para o processo de script.
Portanto, há uma solução para sua tarefa, você pode fazer kill -1 PPID
(processo de script) para reconhecer SIGHUP no processo de script e, em seguida, kill -1 PID
(processo de suspensão). Agora o processo de script fará o manipulador SIGHUP antes de sair, feliz hacking:)
Nem todos os sinais são iguais, por ex. SIGKILL não é permitido capturar . Se você matar -9 o processo de script, o processo de suspensão ainda estará em execução e seu PID pai será 1 (verifique por ps -ef
).
[UPDATE]:
Normalmente, kill -N script_PID
mata diretamente o script se o sinal N não prender no seu script . Mas tenha cuidado com o SIGINT, kill -2 script_PID
não irá matar diretamente, mesmo que o seu script não o prenda. Seu roteiro irá aguardar seu processo filho (por exemplo, dormir 10) feito. Agora, suponha que você faça vários kill em script_PID, ou seja, kill -2 script_PID
AND kill -user-defined_trap_N script_PID
e, em seguida:
- Se o sleep retornar normalmente após 10 segundos de espera OU matar por outro sinal diferente de 2 , seu script ignorará o sinal 2 em cache quando retornar, e então executará o função defined_trap_N.
- Mas se dormir matar pelo sinal 2 , seu script executará o manipulador SIGINT integrado quando retornar e, em seguida, eliminará diretamente sem executar user-defined_trap_N.