O que você está observando é um bug nesta versão do bash.
kill -9 %1
mata o trabalho imediatamente. Você pode observar isso com ps
. Você pode rastrear o processo bash para ver quando a chamada do sistema kill
é chamada e rastrear o subprocesso para ver quando ele recebe e processa os sinais. Mais interstingly, você pode ir e ver o que está acontecendo com o processo.
bash-4.3$ sleep 9999
^Z
[1]+ Stopped sleep 9999
bash-4.3$ kill -9 %1
[1]+ Stopped sleep 9999
bash-4.3$ jobs
[1]+ Stopped sleep 9999
bash-4.3$ jobs -l
[1]+ 3083 Stopped sleep 9999
bash-4.3$
Em outro terminal:
% ps 3083
PID TTY STAT TIME COMMAND
3083 pts/4 Z 0:00 [sleep] <defunct>
O subprocesso é um zumbi . Está morto: tudo o que resta dele é uma entrada na tabela de processos (mas sem memória, código, arquivos abertos, etc.). A entrada é deixada até que seus pais tomem conhecimento e recuperem seu status de saída chamando a wait
chamada de sistema ou um dos seus irmãos .
Um shell interativo deve procurar crianças mortas e colhê-las antes de imprimir um prompt (a menos que seja configurado de outra forma). Esta versão do bash falha em fazer isso em algumas circunstâncias:
bash-4.3$ jobs -l
[1]+ 3083 Stopped sleep 9999
bash-4.3$ true
bash-4.3$ /bin/true
[1]+ Killed sleep 9999
Você pode esperar que o bash relate "Killed" assim que estiver imprimindo o prompt após o comando kill
, mas isso não é garantido, porque há uma condição de corrida. Os sinais são entregues de forma assíncrona: a chamada do sistema kill
retorna assim que o kernel tenha descoberto para qual (is) processo (s) entregar o sinal, sem esperar que ele seja realmente entregue. É possível, e isso acontece na prática, o bash tem tempo para verificar o status de seu subprocesso, descobrir que ele ainda não está morto ( wait4
não relata qualquer morte de criança) e imprimir que o processo ainda está parado . O que está errado é que, antes do próximo prompt, o sinal foi entregue ( ps
informa que o processo está morto), mas o bash ainda não chamou wait4
(podemos ver isso não apenas porque ele ainda relata o trabalho como "Parado", mas porque o zumbi ainda está presente na tabela de processos). Na verdade, o bash só colhe o zumbi na próxima vez que precisar chamar wait4
, quando ele executar outro comando externo.
O bug é intermitente e não consegui reproduzi-lo enquanto o bash é rastreado (presumivelmente porque é uma condição de corrida em que o bash precisa reagir rapidamente). Se o sinal for entregue antes das verificações bash, tudo acontece conforme o esperado.