Mate muitas instâncias de um processo em execução com um comando

75

Suponha que eu tenha mil ou mais instâncias de qualquer processo (por exemplo vi) em execução. Como eu mato todos eles em um único tiro / comando de uma linha / comando?

O Cavaleiro das Trevas
fonte
3
Não está claro para quais sistemas você pretende que isso funcione. Por exemplo, no Linux eu uso pkilldo procpspacote.
Deer Hunter
A pergunta foi feita de um ponto de vista geral. Eu conhecia apenas dois processos como killall e via awk / sed. Mas eu queria saber se existem outras maneiras de conseguir isso. Se for feito de forma diferente em sistemas diferentes, então eu quero saber o que em qual. É muito complicado para o google, em vez disso, pensei em discutir com todos vocês, caras experientes.
O Cavaleiro das Trevas

Respostas:

97

O que há de errado com o bom e velho,

for pid in $(ps -ef | grep "some search" | awk '{print $2}'); do kill -9 $pid; done

Existem maneiras de tornar isso mais eficiente,

for pid in $(ps -ef | awk '/some search/ {print $2}'); do kill -9 $pid; done

e outras variações, mas no nível básico, sempre funcionou para mim.

EightBitTony
fonte
1
Votou, sabia apenas da primeira variação. O segundo parece mais eficiente, obrigado.
O Cavaleiro das Trevas
5
@TheDarkKnight O problema com esse método é que muitas vezes você acaba matando mais do que pretendia. Escrever uma "pesquisa de confiança" confiável é complicado. No Linux, use pkill , que lida com a maioria das sutilezas.
Gilles
Não sei se é complicado, se você estiver atrás de um binário específico, pode ser bastante confiável. Eu sempre corro como o echo kill -9 $pidprimeiro, de qualquer maneira, para saber o que estou recebendo. Não sei se o AIX possui pkill, que é meu UNIX de pão com manteiga. E é realmente ruim o suficiente para ser rebaixado - estranho.
EightBitTony
1
A menos que seja absolutamente necessário, você deve enviar o processo SIGTERM em vez de SIGKILL.
Devo acrescentar que esses 2 métodos não funcionarão em todos os shells, por exemplo, não funcionarãocsh
non sequitor
38

Use killall,

killall vi

Isso matará todo comando chamado 'vi'

Você também pode adicionar um sinal, por exemplo, SIGKILL

killall -9 vi

margarida
fonte
É isso mesmo, você também pode adicionar o sinal que deseja, comokillall -9 vi
Hola Soy Edu Feliz Navidad
1
Eu não acho que killall é a solução: matar por arquivo só funciona para executáveis ​​que são mantidos abertos durante a execução, ou seja, executáveis ​​impuros não podem ser mortos dessa maneira. Digitar killall name pode não ter o efeito desejado em sistemas não Linux, especialmente quando feito por um usuário privilegiado. E se eu estiver tentando excluir muitas instâncias de algum processo não-linux? O killall -w não detecta se um processo desaparece e é substituído por um novo processo com o mesmo PID entre as verificações. Se os processos mudarem de nome, o killall poderá não conseguir correspondê-los corretamente.
O Cavaleiro das Trevas
13
Esteja ciente de que isso só funciona no Linux e BSD. No Solaris e em alguns outros sistemas killall, exatamente o que o nome sugere ... ele mata o processo de inicialização.
Bobby
2
No AIX, "cancela todos os processos iniciados, exceto aqueles que produzem o processo killall".
EightBitTony
31

pkillé o que eu recomendo, se estiver disponível ( Linux , FreeBSD , NetBSD , OpenBSD , Solaris ). Você pode especificar processos pelo nome do comando, pela linha de comando completa ou por outros critérios. Por exemplo, pkill vimata todos os programas cujo nome de comando contém a substring vi. Para matar apenas os processos chamados vi, use pkill -x vi. Para matar apenas processos chamados vicom um último argumento terminado em .conf, use pkill -fx 'vi.*\.conf'.

Para ver a lista de PIDs que pkillenviariam um sinal para use pgrep, que possui exatamente a mesma sintaxe, exceto que não aceita um nome ou número de sinal. Para ver mais informações sobre esses processos, execute

ps -p "$(pgrep …)"

No Linux, você precisa ps -p $(pgrep -d, …)(isso é um bug: o Linux psnão é compatível com POSIX).

Outra maneira comum de identificar processos a serem eliminados são os processos que têm um determinado arquivo aberto (que pode ser o executável do processo). Você pode listá-las com fuser; use fuser -kpara enviar um sinal a eles. Por exemplo, fuser -k /usr/bin/findmata todas as isntances em execução de find.

Se houver um processo descontrolado que continua bifurcando, pode ser necessário matar o grupo de processos inteiro de uma só vez. Um grupo de processos é identificado pelo negativo de seu líder, que é o processo ancestral de todos os processos no grupo. Para ver o grupo de processos ao qual um processo pertence, execute ps -o pgid(mais qualquer opção para selecionar quais processos exibir). Se você determinar que deseja matar o líder do grupo de processos 1234 e todos os seus filhos, execute kill -1234ou kill -HUP -1234ou qualquer outro sinal.

Se você não encontrar uma maneira melhor, use psas opções adequadas para listar todos os processos e filtrá-lo com grepou algum outro comando de filtragem de texto. Tome cuidado para não coincidir acidentalmente com outros processos que estejam executando um comando com um nome semelhante ou com um argumento que contenha esse nome. Por exemplo:

kill $(ps -o pid -o comm | awk '$2 == "vi" {print $1}')

Lembre-se de que o seu comando grepou awkpode estar listado na pssaída ( pse o comando de filtragem é iniciado em paralelo, portanto, se ele será exibido ou não, depende do tempo). Isso é particularmente importante se os argumentos do comando estiverem incluídos na pssaída.

Gilles
fonte
Muito obrigado, isso é realmente incrível. O que você deu é uma espécie de tutorial. Obrigado novamente . Up vote
O Cavaleiro das Trevas
6

pkillé muito legal aqui. Você pode fornecer muitos parâmetros para refinar o padrão.

Nils
fonte
Não disponível em todos os UNIXes, e nenhuma menção a um SO UNIX ou UNIX específico específico na questão.
EightBitTony
O @EightBitTony pkillestá disponível no Linux, BSD e Solaris - afaik. Portanto, tem uma propagação maior que killall.
Nils
Eu concordo, mas o killall é ainda mais problemático porque existem várias ferramentas com o mesmo nome, que parecem ter um comportamento dramaticamente diferente. Também não gosto das respostas killall. O pkill não existe no AIX ou no HP-UX e, apesar do que algumas pessoas gostam de acreditar, ainda existe um número significativo de UNIX não Linux no mundo.
EightBitTony
1
@EightBitTony, é por isso que sua resposta é aceita. Mas eu não o usaria no Solaris (que também é Unix).
Nils
6

A maneira mais fácil de fazer isso é verificar primeiro se você está obtendo os IDs de processo corretos com:

pgrep -f [part_of_a_command]

Se o resultado for o esperado. Ir com:

pkill -f [part_of_a_command]
Tahsin Turkoz
fonte
ou use:pgrep -f "command name"
Magne
3

Interessante ninguém mencionou este. pidof gera pids separados por espaço de processos que correspondem ao nome do processo passado. Como tal, você pode usar diretamente sua saída killsem tubulação. No Arch Linux eu uso

kill -9 $(pidof <proc name>)

A desvantagem desta solução é que ela não permite o uso de expressões regulares.

sherrellbc
fonte
0

Eu sugiro que você tente pkill.

Ex: ps -ef | pkill -f command

Para mostrar a lista de todos os processos a serem eliminados, primeiro tente pgrep:

Ex: ps -ef | pgrep -f command

Ankit Vashistha
fonte
1
Qual é o objetivo de canalizar a saída ps -efpara pkillou pgrep? Esses comandos não são lidos da entrada padrão.
Kusalananda
0

Você pode matar vários processos diferentes usando o comando abaixo

pkill -9 -f "\.\/.+\s\.|process1|process2|process3\[^"

Observe que isso matará o processo que corresponde ao padrão acima; os meios process1abc process2def process3ghitambém serão mortos.

SandPox
fonte
-1

pgrep "name-of-application" | xargs kill -9

Foi simples o suficiente para lembrar e funcionou bem para mim.

Horv
fonte
-2
$ ps -eaf  | grep "xyz" | grep -v grep | awk 'print $2' | xargs kill
user110509
fonte
-2
ps -ef | pgrep -f "search" | xargs kill -9  
Avijit Dhar
fonte