Trova e uccidi un processo in una riga usando bash e regex


650

Spesso devo interrompere un processo durante la programmazione.

Il modo in cui lo faccio ora è:

[~]$ 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

Come posso estrarre automaticamente l'id del processo e ucciderlo nella stessa riga?

Come questo:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>

3
Credimi! : 'D La prima risposta che hai selezionato è molto più complessa della soluzione che hai indicato nella tua risposta. Preferirei scegliere la tua strada.
Santosh Kumar,

modo migliore per verificare se il processo esiste: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Risposte:


1400

In bash, dovresti essere in grado di fare:

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

I dettagli sul suo funzionamento sono i seguenti:

  • Il ps ti dà la lista di tutti i processi.
  • I grepfiltri che in base alla stringa di ricerca,[p] sono un trucco per impedirti di raccogliere il grepprocesso stesso.
  • Il awk giusto ti dà il secondo campo di ogni riga, che è il PID.
  • Il $(x)costrutto significa eseguire xquindi prendere il suo output e inserirlo nella riga di comando. L'output di quella pspipeline all'interno di quel costrutto sopra è la lista degli ID di processo in modo da finire con un comando similekill 1234 1122 7654 .

Ecco una trascrizione che lo mostra in azione:

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 puoi vederlo terminare tutti i dormienti.


Spiegare il grep '[p]ython csp_build.py' bit in modo un po 'più dettagliato:

Quando lo fai sleep 3600 &seguito ps -ef | grep sleep, tendi ad avere due processi con sleepin esso, il sleep 3600e il grep sleep(perché entrambi hannosleep in loro, questa non è scienza missilistica).

Tuttavia, ps -ef | grep '[s]leep'non creerà un processo con sleepal suo interno, crea invece grep '[s]leep'ed ecco il trucco: grepnon lo trova perché sta cercando l'espressione regolare "qualsiasi personaggio della classe di caratteri [s](che è s) seguito daleep .

In altre parole, sta cercando sleepma il processo grep è grep '[s]leep'che non hasleep in esso.

Quando mi è stato mostrato questo (da qualcuno qui su SO), ho immediatamente iniziato a usarlo perché

  • è un processo in meno rispetto all'aggiunta | grep -v grep ; e
  • è elegante e subdolo, una combinazione rara :-)

2
@paxdiablo, puoi fornire un link per questo? Sono sconcertato perché funziona.
Glenn Jackman,

58
Puoi usare solo awk - ps aux | awk '/ [b] eam / {print $ 2}' , non è necessario grep
Yola

20
Meglio usare solo pgrep o pkill
NGix il

2
C'è un piccolo problema - se il processo è già stato terminato, questa linea di killsfornerà con l'output standardkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan

5
Invece di grep '[p]ython csp_build.py'È inoltre possibile utilizzare: kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vrestituisce righe non corrispondenti.
usandfriends

138

se hai pkill,

pkill -f csp_build.py

Se vuoi solo fare grep contro il nome del processo (invece che l'elenco completo degli argomenti), lascia perdere -f.


1
Non è successo nulla quando l'ho provato.
Orjanp,

8
usa prima pgrep per verificare di aver superato il processo corretto. quindi usa di nuovo pkill sul modello corretto.
ghostdog74,

18
+1. pgrepe pkilllavorare fintanto che ti occupi di specificare correttamente il processo. Per impostazione predefinita , viene associato solo il nome del processo , che in questo caso è quasi sicuramente "python". Utilizzare pgrep -f "python csp_build.py"per abbinare il comando completo.
mr.spuratic

3
Potrebbe essere necessario forzare l'uccisione conpkill -9 -f csp_build.py
studgeek il

1
Questa dovrebbe davvero essere la risposta accettata e votata per eccellenza; questi altri con tutto il risveglio sono un po 'inutili. Spero che le persone che trovano questa pagina leggano oltre quella prima risposta.
Jason C,

89

Una fodera:

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

  • Stampa colonna 2: awk '{print $2}'
  • sudo è facoltativo
  • Esegui kill -9 5124, kill -9 5373ecc. (Uccidere -15 è più grazioso ma leggermente più lento)

Bonus:

Ho anche 2 funzioni di collegamento definite nel mio .bash_profile (~ / .bash_profile è per osx, devi vedere cosa funziona per la tua macchina * nix).

  1. parola chiave p
    • elenca tutto P rocesses contenenti parole chiave
    • utilizzo ad es .: p csp_build, p pythonecc

codice bash_profile:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. parola chiave ka
    • K ills A processi ll che hanno questa parola chiave
    • utilizzo ad es .: ka csp_build,ka pythonecc
    • livello di uccisione opzionale ad es .: ka csp_build 15,ka python 9

codice 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"
}

Promemoria : non dimenticare di riavviare la shell bash (terminale) per caricare le nuove funzioni. OPPURE eseguire source ~/.bash_profilenella shell corrente per importare le nuove funzioni (questo è ciò che preferisco).
a20

Come molte altre risposte qui, questo soffre enormemente di un uso inutile digrep . Ricorda, tutto ciò che sembra grep x | awk '{ y }'è di solito migliore e spesso più robusto se lo sostituisci conawk '/x/ { y }'
tripleee

1
@tripleee il sito web a cui stai collegando appartiene a te giusto? Ho notato che lo stai collegando in tutte le varie sezioni dei commenti. Stai cercando di costruire SEO?
a20

No, non mi interessa il SEO. Spero di aumentare la consapevolezza.
Tripleee

1
.. collegandosi al tuo sito Web come se fosse un sito di autorità stabilito. Bello. Inoltre, grep è più veloce .
a20

16
killall -r regexp

-r, --regexp

Interpretazione del modello del nome del processo come espressione regolare estesa.


15

Prova a usare

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill

Ho dovuto cambiarlo un po '. Questo ha funzionato. Grazie. :) ps aux | grep 'python csp_build.py' | testa -1 | cut -d "" -f 5 | xargs kill
Orjanp,

3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killha funzionato per me. grazie
Rasika Perera,

Ricorda, ragazzi, Awk può fare tutto il greppossibile, e la maggior parte in modo semplice ed elegante. Il caso banale di grep x y | awk '{ z }'è sempre meglio scritto awk '/x/ { z }' y- vedi anche l' uso inutile digrep .
triplo il

12

Puoi usare solo pkill '^python*'per uccidere il processo regex.

Se vuoi vedere cosa ucciderai o troverai prima di uccidere, usa pgrep -l '^python*'dove -l genera anche il nome del processo. Se non si desidera utilizzare pkill, utilizzare solo:

pgrep '^python*' | xargs kill


8

Usa pgrep - disponibile su molte piattaforme:

kill -9 `pgrep -f cps_build`

pgrep -f restituirà tutti i PID con coincidenza "cps_build"


2
Se hai pgrep, avrai anche pkill. Come sempre, non utilizzare akill -9 meno che non si sappia perché kill -15(impostazione predefinita) o kill -2non funzionerà.
Tripleee,

Sembra una parafrasi peggiore della risposta di @ nathanael che omette i mal indirizzati -9e usa la sintassi moderna e appropriata per la sostituzione dei comandi. Votalo invece; anche se ovviamente la pkillrisposta è ancora migliore.
Tripleee,

@tripleee In questo caso, uccidere -9 è esattamente quello che voglio - terminare tutti i trasgressori con estremo pregiudizio. Inoltre, ho usato kill -9 per molti anni senza problemi. Secondo me, ci sarà sempre un campo di puristi contro un campo di realisti ben fatti, e io appartengo a quest'ultimo (in questa materia).
a20

Ti sei perso la parte "se non sai perché"? Sono tutto per fare le cose, ma questo è uno dei modi più comuni di spararti nel piede fino a quando non capisci cosa -9significa effettivamente.
triplo il

@tripleee hey tripleee, di recente ho scoperto che hai ragione, uccidere -15 è una scelta migliore perché dà all'app la possibilità di uccidersi con grazia. Ho cambiato il mio codice di conseguenza: stackoverflow.com/a/30486159/163382
A20

7

Questo restituirà solo il pid

pgrep -f 'process_name'

Quindi, per terminare qualsiasi processo in una riga:

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

oppure, se conosci il nome esatto del processo, puoi provare anche pidof:

kill -9 $(pidof 'process_name')

Ma, se non si conosce il nome esatto del processo, pgrepsarebbe meglio.

Se sono in esecuzione più processi con lo stesso nome e si desidera terminare il primo:

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

Inoltre, se sei preoccupato per la distinzione tra maiuscole e minuscole, puoi aggiungere l'opzione -i proprio come in grep. Per esempio:

kill -9 $(pgrep -fi chrome)

Maggiori informazioni su segnali e pgrep su man 7 signalo man signaleman pgrep


5

puoi farlo con awk e backtics

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

$ 2 in awk stampa la colonna 2 e il backtics esegue l'istruzione stampata.

Ma una soluzione molto più pulita sarebbe che il processo python memorizzi il suo ID di processo in / var / run e quindi puoi semplicemente leggere quel file e ucciderlo.


Allora non ucciderai entrambi i processi 5124 e 5373? Immagino che questo non sia un problema.
Orjanp,

non dovrebbe essere un problema, ma puoi sempre aggiungere un altro grep per escludere il processo grep: "grep -v grep" tra grep e awk
Alexander Kjäll,

Testato con un comando leggermente modificato. Ma non ha ucciso il processo, solo stampato kill <pid>. ps auxf grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}'
Orjanp,

Necessario solo per scambiare l'istruzione "kill" $ 2 con un sistema ("kill" $ 2). Quindi funziona. :)
Orjanp,

5

Il mio compito era quello di uccidere tutto ciò che corrispondeva a regexp che si trova in una directory specifica (dopo che i test del selenio non si sono fermati). Questo ha funzionato per me:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done

L' -9opzione di killforse è troppo aggressiva. Ciò non consente loro di liberare le proprie risorse.
Birei,

Bello! L'unico che considera il fatto che potrebbe esserci più di un processo di abbinamento! Una piccola nota: forse potresti voler aggiungere un "grep -v grep" o qualcosa del genere alle pipe, per assicurarti che il processo grep stesso non compaia nella tua lista dei processi.
Brad Parks,

killaccetta più processi, quindi il ciclo è sostanzialmente inutile; e come notato altrove in questa pagina, non dovresti usare a kill -9meno che tu non sappia che il processo non risponderà al giusto kill.
tripla il

rimuovere -9 non è un grosso problema, perché ridimensionare. Faresti meglio a modificare la risposta.
Serge,

5

Per terminare il processo per parola chiave midori, ad esempio:

kill -SIGTERM $(pgrep -i midori)


3

Un metodo che utilizza solo awk(e ps):

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

Usando il test di uguaglianza delle stringhe impedisco di abbinare questo processo stesso.


Per qualche ragione non ottengo un successo su "python csp_build.py". Ma "Python" colpisce da solo.
Orjanp,

3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15

Impossibile +1 a causa del limite giornaliero, ma vale la pena utilizzarlo pscon l' -oopzione.
P:

ps non mi dai molto. [~] $ ps PID TTY TIME CMD 6365 punti / 6 00:00:00 ps 29112 punti / 6 00:00:00 bash
Orjanp

3

Dare -f a pkill

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

il percorso esatto del file .py è

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

2

Ho iniziato a usare qualcosa del genere:

kill $(pgrep 'python csp_build.py')

1

Uccidere i nostri processi partendo da un PPID comune è abbastanza frequente, pkill associato alla –Pbandiera è un vincitore per me. Usando l'esempio di @ 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

1

Non è necessario il cambio utente per ps.

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

1

In alcuni casi, mi piacerebbe uccidere i processi contemporaneamente in questo modo:

➜ ~ dormire 1000 e
[1] 25410
➜ ~ dormire 1000 e
[2] 25415
➜ ~ dormire 1000 e
[3] 25421
~ Pidof sleep
25421 25415 25410
Kill ~ uccidi `pidof sleep`
[2] - 25415 sonno terminato 1000                                                             
[1] - 25410 sleep terminato 1000
[3] + 25421 sonno terminato 1000

Ma penso che sia un po 'inappropriato nel tuo caso (potrebbe esserci in esecuzione python a, python b, python x ... in background).


1

Se pkill -f csp_build.pyil processo non viene -9interrotto, è possibile aggiungerlo per inviare un segnale di errore che non verrà ignorato. vale a direpkill -9 -f csp_build.py


1

La soluzione consisterebbe nel filtrare i processi con un modello esatto, analizzare il pid e costruire un elenco di argomenti per l'esecuzione dei processi di interruzione:

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

Spiegazione dalla documentazione:

L' utilità ps visualizza una riga di intestazione, seguita da righe contenenti informazioni su tutti i processi che hanno terminali di controllo.

-e Visualizza informazioni sui processi di altri utenti, inclusi quelli

-f Visualizza uid, pid, pid parent, utilizzo recente della CPU, avvio del processo

L' utilità grep cerca qualsiasi dato file di input, selezionando le righe

-e pattern, --regexp = pattern Specifica un modello usato durante la ricerca dell'input: viene selezionata una linea di input se corrisponde a uno dei pattern specificati. Questa opzione è particolarmente utile quando vengono utilizzate più opzioni -e per specificare più motivi o quando un motivo inizia con un trattino (`- ').

xargs - costruisce una lista di argomenti ed esegue l'utilità

kill - termina o segnala un processo

segnale numero 9 - KILL (uccisione non catchable, non ignorabile)

Esempio :

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

0

Lo uso per uccidere Firefox quando viene sbattuto lo script e cpu bashing :) Sostituisci "Firefox" con l'app che vuoi morire. Sono sulla shell Bash - OS X 10.9.3 Darwin.

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


La sostituzione grep Firefox | awk 'NR == 1 { next } ...'con awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'non solo salva un processo, ma migliora anche la precisione. Non è difficile sbarazzarsi di sort | uniqin Awk puro (anche se ovviamente uniq | sortè semplicemente sbagliato - mancherà qualsiasi duplicato che non è adiacente e nasconderà l'errore ordinando inutilmente l' output di uniq).
tripla il

0

Uso gkill processname, dove gkill è il seguente 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: NON ucciderà i processi che hanno "grep" nelle loro linee di comando.


1
Come le molte, molte altre reinvenzioni del capannone di yak, questo è pieno di un uso inutilegrep e di altri modelli di script di shell comuni.
Tripleee,

-1

Il seguente comando sarà utile:

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

per esempio., 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 il processo è ancora bloccato, utilizzare l'estensione "-9" per hardkill, come segue:

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

Spero che aiuti...!


-1

Trova e uccidi tutti i processi in una riga in bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Fornisce l'elenco dei dettagli del processo in esecuzione (uname, pid, ecc.) Che corrisponde al modello. L'elenco di output include anche questo grepcomando che lo cerca. Ora per uccidere dobbiamo ignorare questo grepprocesso di comando.
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- L'aggiunta di un altro grep con -v 'grep'rimuove l'attuale processo grep.
  • Quindi utilizzando awkget id processo da solo.
  • Quindi tieni questo comando dentro $(...)e passalo al killcomando, per terminare tutto il processo.

-1

È possibile utilizzare il comando seguente per elencare il pid del comando. Usa top o meglio usa htop per visualizzare tutti i processi in linux. Qui voglio uccidere un processo chiamato

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

E verifica il pid. Deve essere corretto. Per ucciderli usa il comando kill.

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

Ad esempio: - proviene dall'elenco dei processi htop.

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

Questo risolve i miei problemi. Preparati sempre a riavviare il processo se si interrompe accidentalmente un processo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.