Em um comentário sobre esta resposta de outra pergunta , o comentador diz:
não use kill -9 a menos que seja absolutamente necessário! O SIGKILL não pode ser capturado, então o programa morto não pode executar nenhuma rotina de desligamento para, por exemplo, apagar arquivos temporários. Primeiro tente HUP (1), depois INT (2), depois SAIR (3)
Concordo em princípio sobre SIGKILL
, mas o resto é novidade para mim. Dado que o sinal padrão enviado por kill
é SIGTERM
, espero que seja o sinal mais comumente esperado para o desligamento normal de um processo arbitrário. Além disso, tenho visto isso SIGHUP
usado por razões não encerradas, como dizer a um daemon "releia seu arquivo de configuração". E me parece que SIGINT
(a mesma interrupção que você normalmente obteria com Ctrl-C, certo?) Não é tão amplamente suportada quanto deveria, ou termina de forma bastante desagradável.
Dado que SIGKILL
é um último recurso - Quais sinais, e em que ordem , você deve enviar para um processo arbitrário, a fim de encerrá-lo o mais normalmente possível?
Por favor, fundamentar suas respostas com fatos de apoio (além de preferência pessoal ou opinião) ou referências, se você puder.
Nota: Estou particularmente interessado nas melhores práticas que incluem a consideração de bash / Cygwin.
Edit: Até agora, ninguém parece mencionar INT ou QUIT, e há uma menção limitada de HUP. Há alguma razão para incluí-los em um processo de eliminação ordenado?
fonte
Respostas:
SIGTERM diz a um aplicativo para encerrar. Os outros sinais informam ao aplicativo outras coisas que não estão relacionadas ao encerramento, mas às vezes podem ter o mesmo resultado. Não use isso. Se você quiser que um aplicativo seja encerrado, diga para ele. Não dê sinais enganosos.
Algumas pessoas acreditam que a maneira padrão inteligente de encerrar um processo é enviando uma série de sinais, como HUP, INT, TERM e finalmente KILL. Isto é ridículo. O sinal certo para a finalização é o SIGTERM e se o SIGTERM não finalizar o processo instantaneamente, como você pode preferir, é porque o aplicativo escolheu tratar o sinal. O que significa que ele tem um bom motivo para não encerrar imediatamente: ele precisa de um trabalho de limpeza. Se você interromper o trabalho de limpeza com outros sinais, não há como dizer quais dados da memória ainda não foram salvos no disco, quais aplicativos cliente foram deixados pendurados ou se você os está interrompendo "no meio", o que é, efetivamente, corrupção de dados.
Para obter mais informações sobre o real significado dos sinais, consulte sigaction (2). Não confunda "Ação Padrão" com "Descrição", pois elas não são a mesma coisa.
SIGINT é usado para sinalizar uma "interrupção de teclado" interativa do processo. Alguns programas podem lidar com a situação de uma maneira especial para os usuários do terminal.
SIGHUP é usado para sinalizar que o terminal desapareceu e não está mais olhando para o processo. Isso é tudo. Alguns processos optam por encerrar em resposta, geralmente porque sua operação não faz sentido sem um terminal, alguns optam por fazer outras coisas, como verificar novamente os arquivos de configuração.
O SIGKILL é usado para remover o processo do kernel à força. É especial no sentido de que não é realmente um sinal para o processo, mas é interpretado diretamente pelo kernel.
Não envie SIGKILL. O SIGKILL certamente nunca deve ser enviado por scripts. Se o aplicativo manipular o SIGTERM, pode levar um segundo para limpar, pode demorar um minuto, pode levar uma hora . Dependendo do que o aplicativo precisa ser feito antes de estar pronto para terminar. Qualquer lógica que " presume " que a sequência de limpeza de um aplicativo tenha demorado o suficiente e precise ser atalho ou SIGKILL após X segundos está simplesmente errada .
A única razão pela qual um aplicativo precisaria de um SIGKILL para encerrar é se algo deu um bug durante sua sequência de limpeza. Nesse caso, você pode abrir um terminal e SIGKILL manualmente. Além disso, a única outra razão pela qual você SIGKILL algo é porque QUER evitar que ele se limpe sozinho.
Mesmo que metade do mundo envie SIGKILL cegamente após 5 segundos, ainda é uma coisa terrivelmente errada a se fazer.
fonte
Resposta curta : Enviar
SIGTERM
, 30 segundos depoisSIGKILL
,. Ou seja, mandeSIGTERM
, espere um pouco (pode variar de programa para programa, você pode conhecer melhor o seu sistema, mas de 5 a 30 segundos é o suficiente. Ao desligar uma máquina, você pode vê-la esperando automaticamente até 1min30s). Por que a pressa, afinal?), Então envieSIGKILL
.Resposta razoável :
SIGTERM
,SIGINT
,SIGKILL
Isto é mais do que suficiente. O processo muito provavelmente terminará antesSIGKILL
.Longa Resposta :
SIGTERM
,SIGINT
,SIGQUIT
,SIGABRT
,SIGKILL
Isso é desnecessário, mas pelo menos você não está enganando o processo em relação à sua mensagem. Todos estes sinais não significa que você deseja que o processo de parar o que está fazendo e sair.
Não importa a resposta que você escolha nesta explicação, tenha isso em mente!
Se você enviar um sinal que significa outra coisa, o processo pode lidar com isso de maneiras muito diferentes (por um lado). Por outro lado, se o processo não manipular o sinal, não importa o que você envie, o processo será encerrado de qualquer maneira (quando a ação padrão é encerrar, é claro).
Portanto, você deve pensar como um programador. Você codificaria um manipulador de função para, digamos,
SIGHUP
encerrar um programa que se conecta a algo, ou faria um loop para tentar se conectar novamente? Essa é a principal questão aqui! É por isso que é importante apenas enviar sinais que significam o que você pretende.Resposta longa quase estúpida :
A tabela abaixo contém os sinais relevantes e as ações padrão caso o programa não as manipule.
Eu os encomendei na ordem que sugiro usar (BTW, eu sugiro que você use a resposta razoável , não esta aqui), se você realmente precisar experimentar todos (seria divertido dizer que a mesa está ordenada em termos de a destruição que podem causar, mas isso não é totalmente verdade).
Os sinais com um asterisco (*) NÃO são recomendados. O importante é que você nunca sabe o que está programado para fazer. Especialmente
SIGUSR
! Pode iniciar o apocalipse (é um sinal gratuito para um programador fazer o que quiser!). Mas, se não for tratado OU no caso improvável de ser tratado para encerrar, o programa será encerrado.Na tabela, os sinais com opções padrão para encerrar e gerar um core dump são deixados no final, um pouco antes
SIGKILL
.Então eu sugiro para esta longa resposta quase estúpido :
SIGTERM
,SIGINT
,SIGHUP
,SIGPIPE
,SIGQUIT
,SIGABRT
,SIGKILL
E finalmente, o
Definitivamente estúpido, longa resposta longa :
Não tente isto em casa.
SIGTERM
,SIGINT
,SIGHUP
,SIGPIPE
,SIGALRM
,SIGUSR2
,SIGUSR1
,SIGQUIT
,SIGABRT
,SIGSEGV
,SIGILL
,SIGFPE
E se nada funcionou,SIGKILL
.SIGUSR2
deve ser tentado antesSIGUSR1
porque é melhor se o programa não lidar com o sinal. E é muito mais provável que funcioneSIGUSR1
se manipular apenas um deles.BTW, o KILL : não é errado enviar
SIGKILL
para um processo, como outra resposta afirmava. Bem, pense no que acontece quando você envia umshutdown
comando? Vou tentarSIGTERM
eSIGKILL
só. Por que você acha que é o caso? E por que você precisa de quaisquer outros sinais, se o próprioshutdown
comando usa apenas esses dois?Agora, de volta à resposta longa , esta é uma linha on-line interessante:
for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done
Ele dorme por 30 segundos entre os sinais. Por que mais você precisaria de um oneliner ? ;)
Além disso, recomendado: experimente apenas com sinais
15 2 9
da resposta razoável .segurança : remova o segundo
echo
quando estiver pronto para ir. Eu chamo de meudry-run
para onliners . Sempre use-o para testar.Script kill graciosamente
Na verdade, fiquei tão intrigado com essa pergunta que decidi criar um pequeno script para fazer exatamente isso. Fique à vontade para fazer o download (clonar) aqui:
Link do GitHub para o repositório Killgracefully
fonte
Normalmente você enviaria
SIGTERM
, o padrão de matar. É o padrão por um motivo. Somente se um programa não for encerrado em um período de tempo razoável, você deverá recorrer a eleSIGKILL
. Mas note que comSIGKILL
o programa não há possibilidade de limpar as coisas e os dados podem ser corrompidos.Quanto a
SIGHUP
,HUP
significa "desligar" e, historicamente, significa que o modem foi desconectado. É essencialmente equivalente aSIGTERM
. A razão que os daemons às vezes usamSIGHUP
para reiniciar ou recarregar a configuração é que os daemons se desconectam de quaisquer terminais de controle, pois um daemon não precisa deles e, portanto, nunca receberiaSIGHUP
, de modo que o sinal foi considerado como "liberado" para uso geral. Nem todos os daemons usam isso para recarregar! A ação padrão para SIGHUP é encerrar e muitos daemons se comportam dessa maneira! Então você não pode ir às cegas enviandoSIGHUP
s para daemons e esperando que eles sobrevivam.Editar:
SIGINT
é provavelmente impróprio para encerrar um processo, já que normalmente está vinculado a^C
ou qualquer que seja a configuração do terminal para interromper um programa. Muitos programas capturam isso para seus próprios fins, portanto, é comum o suficiente para que não funcione.SIGQUIT
normalmente tem o padrão de criar um dump de memória e, a menos que você queira arquivos de núcleo espalhados, também não é um bom candidato.Resumo: se você enviar
SIGTERM
e o programa não morrer dentro do seu prazo, envie-oSIGKILL
.fonte
SIGTERM
na verdade, significa enviar uma mensagem a um aplicativo: " você seria tão gentil e cometeria suicídio ". Ele pode ser capturado e manipulado pelo aplicativo para executar o código de limpeza e encerramento.SIGKILL
não pode ser capturado pelo aplicativo. O aplicativo é encerrado pelo sistema operacional sem nenhuma chance de limpeza.É normal enviar
SIGTERM
primeiro, dormir um pouco e depois enviarSIGKILL
.fonte
fonte
Com toda a discussão acontecendo aqui, nenhum código foi oferecido. Aqui está minha opinião:
#!/bin/bash $pid = 1234 echo "Killing process $pid..." kill $pid waitAttempts=30 for i in $(seq 1 $waitAttempts) do echo "Checking if process is alive (attempt #$i / $waitAttempts)..." sleep 1 if ps -p $pid > /dev/null then echo "Process $pid is still running" else echo "Process $pid has shut down successfully" break fi done if ps -p $pid > /dev/null then echo "Could not shut down process $pid gracefully - killing it forcibly..." kill -SIGKILL $pid fi
fonte
HUP soa como lixo para mim. Eu o enviaria para obter um daemon para reler sua configuração.
SIGTERM pode ser interceptado; seus daemons podem ter um código de limpeza para executar quando receber esse sinal. Você não pode fazer isso por SIGKILL. Assim, com o SIGKILL você não está dando ao autor do daemon nenhuma opção.
Mais sobre isso na Wikipedia
fonte