Encontre e mate um processo em uma linha usando bash e regex

650

Muitas vezes, preciso matar um processo durante a programação.

O jeito que eu faço agora é:

[~]$ ps aux | grep 'python csp_build.py'
user    5124  1.0  0.3 214588 13852 pts/4    Sl+  11:19   0:00 python csp_build.py
user    5373  0.0  0.0   8096   960 pts/6    S+   11:20   0:00 grep python csp_build.py
[~]$ kill 5124

Como posso extrair a identificação do processo automaticamente e matá-la na mesma linha?

Como isso:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
Orjanp
fonte
3
Acredite em mim! : 'D A primeira resposta que você selecionou é muito mais complexa do que a solução que você disse na sua resposta. Prefiro escolher o seu caminho.
precisa
melhor maneira de verificar se existe processo: stackoverflow.com/questions/3043978/...
Trevor Boyd Smith

Respostas:

1400

Em bash, você deve ser capaz de:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

Os detalhes de seu funcionamento são os seguintes:

  • o ps fornece a lista de todos os processos.
  • Os grepfiltros que, com base na sua sequência de pesquisa, [p]são um truque para impedir que você pegue o valor realgrep processo .
  • o awk just fornece o segundo campo de cada linha, que é o PID.
  • A $(x)construção significa executar, em xseguida, pegue sua saída e coloque-a na linha de comando. A saída desse pspipeline dentro dessa construção acima é a lista de IDs de processo, então você termina com um comando como kill 1234 1122 7654.

Aqui está uma transcrição mostrando em ação:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+  Terminated              sleep 3600
[1]   Terminated              sleep 3600
[2]   Terminated              sleep 3600
[3]-  Terminated              sleep 3600
[4]+  Terminated              sleep 3600

e você pode vê-lo terminando todos os dormentes.


Explicando o grep '[p]ython csp_build.py' bit com mais detalhes:

Quando você sleep 3600 &segue ps -ef | grep sleep, você tende a ter dois processos sleepnele, o sleep 3600e o grep sleep(porque ambos têmsleep nele, isso não é ciência do foguete).

No entanto, ps -ef | grep '[s]leep'não criará um processo sleepnele, ele criará, grep '[s]leep'e aqui está a parte complicada: grepnão o encontra porque está procurando a expressão regular "qualquer caractere da classe de caractere [s](que é s) seguido por leep.

Em outras palavras, ele está procurando, sleepmas o processo grep é o grep '[s]leep'que não possui sleep.

Quando me mostraram isso (por alguém aqui no SO), imediatamente comecei a usá-lo porque

  • é um processo a menos do que adicionar | grep -v grep; e
  • é elegante e sorrateira, uma combinação rara :-)
paxdiablo
fonte
2
@paxdiablo, você pode fornecer um link para isso? Estou confuso por que funciona.
precisa saber é o seguinte
58
Você pode usar apenas awk - ps aux | awk '/ [b] eam / {print $ 2}' , sem grep necessário
Yola 15/11
20
Melhor usar apenas pgrep ou pkill
NGix
2
Há um pequeno problema - se o processo já tiver sido encerrado, essa linha de processamento killocorrerá com a saída padrão #kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan
5
Em vez de grep '[p]ython csp_build.py'você também pode usar: kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vretorna linhas não correspondentes.
usandfriends
138

se você tiver pkill,

pkill -f csp_build.py

Se você deseja apenas grep com o nome do processo (em vez da lista completa de argumentos), pare -f.

ghostdog74
fonte
1
Nada aconteceu quando eu testei isso.
Orjanp 18/08/10
8
use o pgrep primeiro para verificar se você cumpriu o processo correto. depois use pkill novamente no padrão correto.
ghostdog74
18
+1. pgrepe pkilltrabalhe contanto que você especifique o processo corretamente. Por padrão, apenas o nome do processo é correspondido, o que quase certamente é apenas "python" neste caso. Use pgrep -f "python csp_build.py"para corresponder ao comando completo.
precisa saber é o seguinte
3
Pode ser necessário forçar a matar compkill -9 -f csp_build.py
studgeek
1
Essa realmente deve ser a resposta aceita e a mais votada; esses outros com todo o despertar são meio desnecessários. Espero que as pessoas que encontrarem esta página leiam além da primeira resposta.
Jason C
89

Um forro:

ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9

  • Imprima a coluna 2: awk '{print $2}'
  • sudo é opcional
  • Run kill -9 5124, kill -9 5373etc (matar -15 é mais graciosa, mas um pouco mais lento)

Bônus:

Eu também tenho 2 funções de atalho definidas no meu .bash_profile (~ / .bash_profile é para osx, você precisa ver o que funciona na sua máquina * nix).

  1. palavra-chave p
    • lista todos os P rocesses contendo palavra-chave
    • utilização, por exemplo: p csp_build, p pythonetc.

código bash_profile:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. palavra-chave ka
    • K ills A processos ll que têm esta palavra-chave
    • utilização, por exemplo: ka csp_build,ka pythonetc.
    • nível matar opcional por exemplo: ka csp_build 15,ka python 9

código bash_profile:

# KILL ALL
function ka(){

    cnt=$( p $1 | wc -l)  # total count of processes found
    klevel=${2:-15}       # kill level, defaults to 15 if argument 2 is empty

    echo -e "\nSearching for '$1' -- Found" $cnt "Running Processes .. "
    p $1

    echo -e '\nTerminating' $cnt 'processes .. '

    ps aux  |  grep -i $1 |  grep -v grep   | awk '{print $2}' | xargs sudo kill -klevel
    echo -e "Done!\n"

    echo "Running search again:"
    p "$1"
    echo -e "\n"
}
a20
fonte
Lembrete - Não esqueça de reiniciar o shell bash (terminal) para carregar as novas funções. OU execute source ~/.bash_profileno shell atual para importar as novas funções (é o que eu prefiro).
a20
Como muitas das outras respostas aqui, isso sofre monumentalmente pelo uso inútil degrep . Lembre-se, qualquer coisa que se parece grep x | awk '{ y }'é geralmente melhor e muitas vezes mais robusto se você substituí-lo comawk '/x/ { y }'
tripleee
1
@tripleee o site ao qual você está vinculando pertence a você, certo? Percebo que você está vinculando tudo nas várias seções de comentários. Você está tentando criar SEO?
a20
Não, não tenho interesse em SEO. Eu espero construir consciência.
tripleee
1
.. vinculando ao seu site como se fosse um site de autoridade estabelecido. Agradável. Além disso, o grep é mais rápido .
a20
16
killall -r regexp

-r, --regexp

Interprete o padrão do nome do processo como uma expressão regular estendida.

Miron Yanovskiy
fonte
15

Tente usar

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
Rahul
fonte
Teve que mudar um pouco. Isso funcionou. Obrigado. :) ps aux | grep 'python csp_build.py' | cabeça -1 | cut -d "" -f 5 | xargs matar
Orjanp
3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killtrabalhou para mim. thanx
Rasika Perera
Lembre-se, crianças, o Awk pode fazer tudo o que greppode, e a maioria simples e elegante. O caso trivial de grep x y | awk '{ z }'é sempre melhor escrito awk '/x/ { z }' y- veja também o uso inútil degrep .
tripleee
12

Você pode usar apenas pkill '^python*'para extermínio de processos regex.

Se você quiser ver o que você irá matar ou encontrar antes de matar, use pgrep -l '^python*'where -l outputs e também o nome do processo. Se você não quiser usar pkill, use apenas:

pgrep '^python*' | xargs kill

NGix
fonte
8

Use pgrep - disponível em várias plataformas:

kill -9 `pgrep -f cps_build`

O pgrep -f retornará todos os PIDs com coincidência "cps_build"

vr286
fonte
2
Se você tiver pgrep, você também terá pkill. Como sempre, não use, akill -9 menos que você saiba o porquê kill -15(o padrão) ou kill -2não funcionará.
Tripleee
Parece uma paráfrase pior da resposta de @ nathanael, que omite o direcionado incorretamente -9e usa a sintaxe adequada de substituição de comandos modernos. Voto positivo em vez disso; embora, é claro, a pkillresposta seja melhor ainda.
Tripleee
@tripleee Nesse caso, matar -9 é exatamente o que eu quero - encerrar todos os infratores com extremo preconceito. Além disso, eu uso o kill -9 há muitos anos sem problemas. Na minha opinião, sempre haverá um campo de puristas versus um campo de realistas do tipo "faça as coisas", e eu pertenço a este último (nesta matéria).
a20 24/01
Você perdeu a parte "a menos que saiba por quê"? Sou a favor de fazer as coisas, mas essa é uma das maneiras mais comuns de dar um tiro no próprio pé até você entender o que -9realmente significa.
tripleee
@ tripleee hey tripleee, recentemente descobri que você está certo, o kill -15 é uma escolha melhor porque oferece ao aplicativo a chance de se matar graciosamente. Alterei meu código de acordo: stackoverflow.com/a/30486159/163382 #
2020
7

Isso retornará apenas o pid

pgrep -f 'process_name'

Então, para matar qualquer processo em uma linha:

kill -9 $(pgrep -f 'process_name')

ou, se você souber o nome exato do processo, também poderá tentar pidof:

kill -9 $(pidof 'process_name')

Mas, se você não souber o nome exato do processo, pgrepseria melhor.

Se houver vários processos em execução com o mesmo nome e você desejar eliminar o primeiro, então:

kill -9 $(pgrep -f 'process_name' | head -1)

Observe também que, se você estiver preocupado com a distinção entre maiúsculas e minúsculas, poderá adicionar a opção -i, como no grep. Por exemplo:

kill -9 $(pgrep -fi chrome)

Mais informações sobre sinais e pgrep em man 7 signalou man signaleman pgrep

Rakib Fiha
fonte
5

você pode fazer isso com awk e backtics

ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`

$ 2 em awk imprime a coluna 2, e o backtics executa a instrução que é impressa.

Mas uma solução muito mais limpa seria para o processo python armazenar sua identificação de processo em / var / run e então você pode simplesmente ler esse arquivo e matá-lo.

Alexander Kjäll
fonte
Você não matará os processos 5124 e 5373 então? Eu acho que isso não é um problema.
Orjanp 18/08/10
ele não deve ser um problema, mas você sempre pode adicionar outro grep para excluir o processo grep: "grep -v grep" entre grep e awk
Alexander Kjäll
Testado com um comando ligeiramente modificado. Mas não matou o processo, apenas matou impresso <pid>. ps auxf | grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}' '
Orjanp
Apenas era necessário trocar a declaração "kill" $ 2 impressa por um sistema ("kill" $ 2). Então funciona. :)
Orjanp
5

Minha tarefa era matar tudo o que correspondia ao regexp que é colocado em um diretório específico (depois dos testes de selênio, nem tudo ficava parado). Isso funcionou para mim:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done
Sarja
fonte
A -9opção de killtalvez seja muito agressiva. Isso não permite que eles liberem seus recursos.
Birei
Agradável! O único que considera o fato de que pode haver mais de um processo de correspondência! Uma pequena nota: talvez você queira adicionar um "grep -v grep" ou algo parecido aos canais, para garantir que o próprio processo grep não apareça na sua lista de processos.
Brad Parks
killaceita vários processos para que o loop seja basicamente inútil; e conforme observado em outras partes desta página, você não deve usá- kill -9lo, a menos que saiba que o processo não responderá apenas kill.
Tripleee
remover -9 não é grande coisa, por que voto negativo. É melhor você editar a resposta.
Serge
5

Para eliminar processo por palavra-chave midori, por exemplo:

kill -SIGTERM $(pgrep -i midori)

l3v1ath4n
fonte
3

Um método usando apenas awk(e ps):

ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'

Usando o teste de igualdade de cadeias, evito corresponder esse processo.

schot
fonte
Por alguma razão, não recebo sucesso em "python csp_build.py". Mas "python" sozinho atinge.
Orjanp 18/08/10
3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
Vijay
fonte
Não é possível marcar com +1 devido ao limite diário, mas vale a pena usar a opção pswith -o.
precisa saber é o seguinte
ps não me dê muito. [~] $ ps TEMPO DE TTY DO PID CMD 6365 pts / 6 00:00:00 ps 29112 pts / 6 00:00:00 bash
Orjanp 18/08/10
3

Dê -f para pkill

pkill -f /usr/local/bin/fritzcap.py

o caminho exato do arquivo .py é

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m
Robert1968
fonte
2

Comecei a usar algo como isto:

kill $(pgrep 'python csp_build.py')
Natanael
fonte
1

Matar nossos próprios processos iniciados a partir de um PPID comum é bastante frequente, o pkill associado à –Pbandeira é um vencedor para mim. Usando o exemplo @ ghostdog74:

# sleep 30 &                                                                                                      
[1] 68849
# sleep 30 &
[2] 68879
# sleep 30 &
[3] 68897
# sleep 30 &
[4] 68900
# pkill -P $$                                                                                                         
[1]   Terminated              sleep 30
[2]   Terminated              sleep 30
[3]-  Terminated              sleep 30
[4]+  Terminated              sleep 30
Juan Diego Godoy Robles
fonte
1

Você não precisa da opção de usuário para ps.

kill `ps ax | grep 'python csp_build.py' | awk '{print $1}'`
Alex V
fonte
1

Em alguns casos, eu gostaria de matar processos simultaneamente desta maneira:

Sleep ~ dormir 1000 e
[1] 25410
Sleep ~ dormir 1000 e
[2] 25415
Sleep ~ dormir 1000 e
[3] 25421
P ~ pidof sono
25421 25415 25410
Kill ~ mate `pidof sono`
[2] - 25415 sono interrompido 1000                                                             
[1] - 25410 sono interrompido 1000
[3] + 25421 sono interrompido 1000

Mas acho que é um pouco inapropriado no seu caso (pode estar executando python a, python b, python x ... em segundo plano).

kashu.org
fonte
1

Se pkill -f csp_build.pynão -9interromper o processo, você pode adicionar para enviar um sinal de interrupção que não será ignorado. iepkill -9 -f csp_build.py

yosemite_k
fonte
1

A solução seria filtrar os processos com o padrão exato, analisar o pid e construir uma lista de argumentos para executar os processos de interrupção:

ps -ef  | grep -e <serviceNameA> -e <serviceNameB> -e <serviceNameC> |
awk '{print $2}' | xargs sudo kill -9

Explicação da documentação:

O utilitário ps exibe uma linha de cabeçalho, seguida por linhas contendo informações sobre todos os seus processos que possuem terminais de controle.

-e Exibe informações sobre os processos de outros usuários, incluindo aqueles

-f Exibe o uid, pid, pai pid, uso recente da CPU, início do processo

O utilitário grep pesquisa qualquer arquivo de entrada, selecionando linhas que

-e padrão, --regexp = padrão Especifique um padrão usado durante a procura da entrada: uma linha de entrada será selecionada se corresponder a qualquer um dos padrões especificados. Essa opção é mais útil quando várias opções -e são usadas para especificar vários padrões ou quando um padrão começa com um traço (`- ').

xargs - constrói lista (s) de argumentos e executa o utilitário

kill - encerra ou sinaliza um processo

sinal número 9 - KILL (morte não capturável e não ignorável)

Exemplo :

ps -ef  | grep -e node -e loggerUploadService.sh - -e applicationService.js |
awk '{print $2}' | xargs sudo kill -9
avivamg
fonte
0

Eu uso isso para matar o Firefox quando ele está sendo executado com scripts e travamento da CPU :) Substitua 'Firefox' pelo aplicativo que você deseja morrer. Estou no shell Bash - OS X 10.9.3 Darwin.

kill -Hup $(ps ux | grep Firefox | awk 'NR == 1 {next} {print $2}' | uniq | sort)

mrhassell
fonte
A substituição grep Firefox | awk 'NR == 1 { next } ...'por awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'não apenas salva um processo, mas também melhora a precisão. Também não é difícil se livrar do sort | uniqAwk puro (embora, uniq | sorté claro, esteja errado - ele perderá as duplicatas que não são adjacentes e ocultará o erro, classificando desnecessariamente a saída de uniq).
tripleee
0

Eu uso gkill processname, onde gkill é o seguinte script:

cnt=`ps aux|grep $1| grep -v "grep" -c`
if [ "$cnt" -gt 0 ]
then
    echo "Found $cnt processes - killing them"
    ps aux|grep $1| grep -v "grep"| awk '{print $2}'| xargs kill
else
    echo "No processes found"
fi

NOTA: NÃO mata processos que tenham "grep" em suas linhas de comando.

Kostyantyn
fonte
1
Como as muitas, muitas outras reinvenções do barracão de iaques, isso está repleto de uso inútilgrep e outros antipadrões comuns de scripts de shell.
Tripleee 27/07
-1

O seguinte comando será útil:

kill $(ps -elf | grep <process_regex>| awk {'print $4'})

por exemplo., ps -elf | grep top

    0 T ubuntu    6558  6535  0  80   0 -  4001 signal 11:32 pts/1    00:00:00 top
    0 S ubuntu    6562  6535  0  80   0 -  2939 pipe_w 11:33 pts/1    00:00:00 grep --color=auto top

kill -$(ps -elf | grep top| awk {'print $4'})

    -bash: kill: (6572) - No such process
    [1]+  Killed                  top

Se o processo ainda estiver travado, use a extensão "-9" para executar o hardkill, da seguinte maneira:

kill -9 $(ps -elf | grep top| awk {'print $4'})

Espero que ajude...!

Akshay Shah
fonte
-1

Encontre e mate todos os processos em uma linha no bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Fornece a lista de detalhes do processo em execução (uname, pid, etc) que correspondem ao padrão. A lista de saída greptambém inclui este comando que o pesquisa. Agora, para matar, precisamos ignorar esse grepprocesso de comando.
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- Adicionar outro grep -v 'grep'remove o processo grep atual.
  • Em seguida, use awkobter o ID do processo sozinho.
  • Em seguida, mantenha esse comando dentro $(...)e passe-o para o killcomando, para matar todo o processo.
rashok
fonte
-1

Você pode usar o comando abaixo para listar o pid do comando. Use top ou melhor, use htop para visualizar todo o processo no linux. Aqui eu quero matar um processo chamado

ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'

E verifique o pid. Para matá-los, use o comando kill.

sudo kill -9 `ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'`

Por exemplo: - é da lista de processos htop.

sudo kill -9 `ps -ef | grep '<process>'  | grep -v grep | awk '{print $2}'`

Isso resolve meus problemas. Sempre esteja preparado para reiniciar o processo se você acidentalmente matar um processo.

shijin
fonte