Alternativa mais amável / mais sutil / mais sutil ao killall (por exemplo, "endall")?

17

Como encerro todos os processos com o mesmo nome de uma maneira mais suave do que killallfaz? Não quero interromper os processos, mas deixe-os tempo para sair corretamente.


Veja também:

Como eu mato processos no Ubuntu?

No System Monitor, qual é a diferença entre Kill Process e End Process?

Por que killall (às vezes?) Precisa ser aplicado duas vezes?

tl; dr

noz sobre natty
fonte
11
E sua pergunta é?
usar o seguinte comando
@ Pilot6 re-formulada: o que é uma "mais suave" alternativa para killall?
noz sobre elegante
11
O que é "mais suave"?
usar o seguinte comando
@ Pilot6 "mais suave", no sentido de sistema do Monitor "End" vs "matar"
noz sobre natty

Respostas:

43

1. `killall` já é legal (SIGTERM)

killallpor padrão envia SIGTERM. Essa é a boa abordagem que deixa os aplicativos com a chance de se limparem. O "vá morrer já, agora!" A abordagem é enviar um SIGKILLsinal, o que requer especificar isso como uma opção para killall. Da Biblioteca GNU C: Sinais de Terminação :

Macro: int SIGTERM

[...] é a maneira normal de pedir educadamente que um programa seja encerrado.


2. O "Processo final" do System Monitor é igualmente agradável (SIGTERM também)

Você está vinculado a uma pergunta sobre o GNOME System Monitor. Isso também é usado SIGTERMpara a ação "Finalizar processo" (e percebo que estou contradizendo a resposta a essa pergunta). Você pode encontrá-lo no código fonte para verificar a si mesmo:

data / menus.ui :

<item>
  <attribute name="label" translatable="yes">_End</attribute>
  <attribute name="action">win.send-signal-end</attribute>
  <attribute name="accel">&lt;Primary&gt;e</attribute>
  <attribute name="target" type="i">15</attribute>
</item>

Os 15 aqui são o número do sinal. O sinal 15 é SIGTERM. E o System Monitor já foi utilizado SIGTERMbem antes que outra pergunta fosse feita e respondida.


Adendo técnico (em resposta a um comentário)

Examinando a representação do Github de git blame, aqui estão as mudanças que foram feitas na forma como os sinais são escritos no código-fonte do GNOME System Monitor:

383007f2 24 de julho de 2013 Código duplicado substituído para enviar sinais com os parâmetros do
GAction 0e766b2d 18 de julho de 2013 Menu pop-up do processo da porta para o GAction
97674c79 3 de outubro de 2012 Livre-se da estrutura do ProcData
38c5296c 3 de julho de 2011 Torne a indentação uniforme nos arquivos de origem.

Nada disso foi alterado de SIGQUITpara SIGTERMe o último foi de antes da pergunta vinculada.

hvd
fonte
7
+1 por se referir ao código fonte! (2 por contradizer "sabedoria convencional", por assim dizer;)
noz sobre elegante
Bem, antes de afirmar que você está contradizendo a resposta: você verificou se todas as versões do código fonte usam 15? Pode ter sido alterado em algum momento, portanto a resposta antiga pode estar 100% correta em relação a uma versão antiga.
Bakuriu 21/09/2015
11
@Bakuriu Eu contradiz essa resposta de qualquer maneira, mas, justamente, tentarei me lembrar de verificar a próxima vez que puder.
hvd
O @Bakuriu na árvore git de origem git grep 'SIGQUIT'não revela nada. Nada relacionado a sinais também é encontrado git grep '>3<'. Concluo que provavelmente o monitor do sistema gnome nunca foi usado SIGQUIT.
Ruslan
@Ruslan git grepapenas pesquisa na árvore atual, não em todo o histórico. Eu usei git blame(na verdade o equivalente ao Github) para cavar um pouco mais fundo, mas ainda nada.
hvd
5

A resposta do @hvd está basicamente correta. Para dar ainda mais suporte, o initprocesso será enviado primeiro SIGTERMaos processos quando você estiver desligando o computador e depois de um atraso será enviado SIGKILLse eles ainda não tiverem saído. Os processos não podem manipular / ignorar SIGKILL.

Para dar um pouco mais de detalhes, a resposta real é que você não tem como saber com certeza que o programa lida com isso. SIGTERMé o sinal mais comum a ser usado para pedir educadamente a um programa para sair, mas toda a manipulação de sinais depende do programa fazer algo com o sinal.

Em outras palavras, com base nas outras respostas, se você tivesse um programa escrito por @Jos ou por @AlexGreg, eles provavelmente estariam lidando com, SIGQUITmas possivelmente não SIGTERM, e, portanto, o envio SIGTERMseria menos "suave" do que SIGQUIT.

Eu escrevi um código para que você possa brincar com ele. Salve o abaixo como signal-test.ce compile com

gcc -o signal-test signal-test.c

Você pode executá-lo ./signal-teste ver o que acontece quando envia sinais diferentes com killall -s <signal>.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int flag = 0;

void handle_signal(int s)
{
    flag = s;
}

int main(int argc, char *argv[])
{
    signal(SIGTERM, handle_signal);
    signal(SIGQUIT, handle_signal);

    while(flag == 0){
        sleep(1);
    }
    printf("flag is %d\n", flag);
    return flag;
}

Tal como está, o código lida com SIGTERM e SIGQUIT normalmente. Você pode tentar comentar as linhas signal(SIG...(usando a //no início da linha) para remover o manipulador de sinais, executar e enviar os sinais novamente. Você poderá ver essas diferentes saídas:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

dependendo se você lida com os sinais ou não.

Você também pode tentar ignorar os sinais:

signal(SIGTERM, SIG_IGN);

Se você fizer isso, o envio SIGTERMnão fará nada, você precisará usar SIGKILLpara finalizar o processo.

Mais detalhes em man 7 signal. Observe que o uso signal()dessa maneira é considerado não portátil - é muito mais fácil do que a alternativa!

Uma outra nota de rodapé menor - no Solaris, killalltenta matar todos os processos. Todos eles. Se você executá-lo como root, poderá se surpreender :)

Roger Light
fonte
11
Essa é uma das razões pelas quais prefiro pkill. A outra razão é que ele é emparelhado pgrep, o que facilita a verificação exata de quais processos serão eliminados e qual ela mesma possui melhor semântica de correspondência do que ps | grep.
usar o seguinte código
1

"Terminar tudo" seria killall -s SIGQUIT [process name]. Se você deseja uma solução sofisticada, defina alias endall='killall -s SIGQUIT'.

Jos
fonte
13
SIGQUITé como fazer o processo abort(3): despeja o núcleo e depois mata o processo. Isso não é de maneira alguma mais agradável / gentil / gentil do SIGTERMque o padrão killall.
Ruslan
3
Para um processo que lida com sinais SIGQUIT(ou melhor ainda SIGINT) , pode ser tratado com mais suavidade do que SIGTERM, mas isso depende da aplicação. Sem tratamento, qualquer um deles causa rescisão imediata.
R .. GitHub Pare de ajudar o gelo
11
Essa é uma ótima idéia, se você gosta de limpar os arquivos principais em todo o seu disco.
Nate Eldredge
2
@ Qix: Uma coisa que varia por sinal é se ele cria um arquivo principal ou não na ação padrão (quando não é tratado pelo aplicativo). Provavelmente é preferível usar sinais que não geram arquivos principais.
R .. GitHub Pare de ajudar o gelo
11
Vale a pena notar que o ubuntu define o limite de tamanho do arquivo principal como 0 por padrão, então o SIGQUIT não produzirá realmente um arquivo principal (se não for tratado), a menos que você modifique o limite.
Roger Light