Finden und beenden Sie einen Prozess in einer Zeile mit Bash und Regex

645

Ich muss oft einen Prozess während der Programmierung beenden.

Ich mache es jetzt so:

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

Wie kann ich die Prozess-ID automatisch extrahieren und in derselben Zeile beenden?

So was:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
Orjanp
quelle
3
Glaube mir! : 'D Die erste Antwort, die Sie ausgewählt haben, ist weitaus komplexer als die Lösung, die Sie in Ihrer Antwort angegeben haben. Ich würde lieber deinen Weg wählen.
Santosh Kumar
Der beste Weg, um zu überprüfen, ob ein Prozess vorhanden ist: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Antworten:

1394

In bashsollten Sie in der Lage sein:

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

Details zu seiner Arbeitsweise sind wie folgt:

  • Das psgibt Ihnen die Liste aller Prozesse.
  • Die grepFilter, die auf Ihrer Suchzeichenfolge basieren, [p]sind ein Trick, um zu verhindern, dass Sie den eigentlichen grepProzess selbst erfassen.
  • Das awkgibt Ihnen nur das zweite Feld jeder Zeile, das die PID ist.
  • Das $(x)Konstrukt bedeutet ausführen, xdann seine Ausgabe nehmen und in die Befehlszeile einfügen. Die Ausgabe dieser psPipeline in diesem Konstrukt oben ist die Liste der Prozess-IDs, sodass Sie am Ende einen Befehl wie erhalten kill 1234 1122 7654.

Hier ist ein Transkript, das es in Aktion zeigt:

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

und Sie können sehen, dass es alle Schläfer beendet.


Das grep '[p]ython csp_build.py'Bit etwas ausführlicher erklären :

Wenn Sie sleep 3600 &gefolgt sind ps -ef | grep sleep, neigen Sie dazu, zwei Prozesse sleepdarin zu haben, den sleep 3600und den grep sleep(weil beide sleepin ihnen sind, ist das keine Raketenwissenschaft).

Es ps -ef | grep '[s]leep'wird jedoch kein Prozess sleepdarin erstellt, sondern es wird erstellt, grep '[s]leep'und hier ist das Knifflige: Das grepfindet es nicht, weil es nach dem regulären Ausdruck "jedes Zeichen aus der Zeichenklasse [s](das folgt s) " sucht leep.

Mit anderen Worten, es wird gesucht, sleepaber der Grep-Prozess ist derjenige, grep '[s]leep'der nicht sleepdarin enthalten ist.

Als mir dies gezeigt wurde (von jemandem hier auf SO), fing ich sofort an, es zu benutzen, weil

  • Es ist ein Prozess weniger als das Hinzufügen | grep -v grep. und
  • es ist elegant und hinterhältig, eine seltene Kombination :-)
paxdiablo
quelle
2
@paxdiablo, können Sie einen Link dafür bereitstellen? Ich bin verblüfft, warum es funktioniert.
Glenn Jackman
58
Sie dürfen nur awk - ps aux | verwenden awk '/ [b] eam / {print $ 2}' , kein grep erforderlich
Yola
20
Besser nur pgrep oder pkill verwenden
NGix
2
Es gibt ein kleines Problem - wenn der Prozess bereits beendet wurde, wird diese Zeile killmit der Standardausgabe ausgegebenkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan
5
Anstelle von können grep '[p]ython csp_build.py'Sie auch verwenden : kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vGibt nicht übereinstimmende Zeilen zurück.
usandfriends
137

wenn du pkill hast,

pkill -f csp_build.py

Wenn Sie nur nach dem Prozessnamen (anstelle der vollständigen Argumentliste) suchen möchten, lassen Sie es aus -f.

Ghostdog74
quelle
1
Als ich das getestet habe, ist nichts passiert.
Orjanp
8
Verwenden Sie zuerst pgrep, um zu überprüfen, ob Sie den richtigen Prozess gefunden haben. Verwenden Sie dann pkill erneut für das richtige Muster.
Ghostdog74
18
+1. pgrepund pkillarbeiten Sie so lange, wie Sie darauf achten, den Prozess korrekt anzugeben. Standardmäßig wird nur der Prozessname abgeglichen, was in diesem Fall mit ziemlicher Sicherheit nur "Python" ist. Verwenden Sie pgrep -f "python csp_build.py"diese Option , um den vollständigen Befehl abzugleichen.
mr.spuratic
3
Möglicherweise müssen Sie die Tötung mitpkill -9 -f csp_build.py
studgeek
1
Dies sollte wirklich die akzeptierte und am besten gewählte Antwort sein; Diese anderen mit all dem Awk'ing sind irgendwie unnötig. Ich hoffe, Leute, die diese Seite finden, lesen über diese erste Antwort hinaus.
Jason C
88

Einzeiler:

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

  • Spalte 2 ausdrucken: awk '{print $2}'
  • sudo es ist optional
  • Run kill -9 5124, kill -9 5373etc (kill -15 ist anmutiger , aber etwas langsamer)

Bonus:

Ich habe auch 2 Verknüpfungsfunktionen in meinem .bash_profile definiert (~ / .bash_profile ist für osx, Sie müssen sehen, was für Ihre * nix-Maschine funktioniert).

  1. p Schlüsselwort
    • Listen aus allen P rozesse Schlüsselwort enthalten
    • Verwendung zB p csp_build, p pythonusw.

bash_profile code:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. ka Schlüsselwort
    • K Übel A ll Prozesse , die dieses Schlüsselwort
    • Verwendung zB ka csp_build, ka pythonusw.
    • optional Kill Ebene zB: ka csp_build 15,ka python 9

bash_profile code:

# 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
quelle
Erinnerung - Vergessen Sie nicht, die Bash-Shell (Terminal) neu zu starten, um die neuen Funktionen zu laden. ODER source ~/.bash_profilein der aktuellen Shell ausführen , um die neuen Funktionen zu importieren (das ist, was ich bevorzuge).
A20
Wie viele der anderen Antworten hier leidet dies monumental unter nutzlosem Gebrauch vongrep . Denken Sie daran, alles, was aussieht, grep x | awk '{ y }'ist normalerweise besser und oft robuster, wenn Sie es durchawk '/x/ { y }'
Tripleee
1
@tripleee die Website, auf die Sie verlinken, gehört Ihnen, oder? Ich stelle fest, dass Sie alles in den verschiedenen Kommentaren verknüpfen. Versuchen Sie, SEO aufzubauen?
A20
Nein, ich habe kein Interesse an SEO. Ich hoffe, Bewusstsein zu schaffen.
Tripleee
1
.. indem Sie auf Ihre Website verlinken, als ob es sich um eine etablierte Behörde handelt. Nett. Außerdem ist grep schneller .
A20
16
killall -r regexp

-r, --regexp

Interpretieren Sie das Prozessnamenmuster als erweiterten regulären Ausdruck.

Miron Yanovskiy
quelle
15

Versuchen Sie es mit

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
Rahul
quelle
Musste es ein bisschen ändern. Das hat funktioniert. Vielen Dank. :) ps aux | grep 'python csp_build.py' | Kopf -1 | cut -d "" -f 5 | Xargs töten
Orjanp
3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killarbeitete für mich. Danke
Rasika Perera
Denken Sie daran, Kinder, Awk kann alles grep, und das meiste einfach und elegant. Der triviale Fall von grep x y | awk '{ z }'ist immer besser geschrieben awk '/x/ { z }' y- siehe auch nutzlose Verwendung vongrep .
Tripleee
11

Sie dürfen nur verwenden pkill '^python*' für das Töten von Regex-Prozessen verwenden.

Wenn Sie sehen möchten, was Sie töten oder finden werden, bevor Sie töten, verwenden Sie einfach, pgrep -l '^python*'wobei -l auch den Namen des Prozesses ausgibt. Wenn Sie nicht verwenden möchten pkill, verwenden Sie einfach:

pgrep '^python*' | xargs kill

NGix
quelle
8

Verwenden Sie pgrep - verfügbar auf vielen Plattformen:

kill -9 `pgrep -f cps_build`

pgrep -f gibt alle PIDs mit dem Zufall "cps_build" zurück.

vr286
quelle
2
Wenn Sie haben pgrep, werden Sie auch haben pkill. Verwendenkill -9 Sie es wie immer nur, wenn Sie wissen, warum kill -15(Standardeinstellung) oder kill -2nicht.
Tripleee
Dies sieht nach einer schlechteren Umschreibung der Antwort von @ nathanael aus, bei der die Fehlleitung weggelassen wird-9 und die richtige moderne Syntax für die Substitution von Befehlen verwendet wird. Stimmen Sie das stattdessen zu; Die pkillAntwort ist natürlich noch besser.
Tripleee
@tripleee In diesem Fall ist kill -9 genau das, was ich will - beende alle Täter mit extremen Vorurteilen. Außerdem habe ich kill -9 viele Jahre ohne Probleme verwendet. Meiner Meinung nach wird es immer ein Lager von Puristen gegen ein Lager von Realisten geben, und ich gehöre zu letzterem (in dieser Angelegenheit).
A20
Haben Sie den Teil "es sei denn, Sie wissen warum" verpasst? Ich bin alles dafür, Dinge zu erledigen, aber dies ist eine der gängigen Methoden, um sich in den Fuß zu schießen, bis Sie verstehen, was das -9eigentlich bedeutet.
Tripleee
@ Tripleee Hey Tripleee, ich habe kürzlich festgestellt, dass Sie Recht haben. Kill -15 ist eine bessere Wahl, da es der App die Möglichkeit gibt, sich selbst anmutig zu töten. Ich habe meinen Code entsprechend geändert: stackoverflow.com/a/30486159/163382
a20
6

Dies gibt nur die PID zurück

pgrep -f 'process_name'

So beenden Sie jeden Prozess in einer Zeile:

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

Wenn Sie den genauen Namen des Prozesses kennen, können Sie auch pidof ausprobieren:

kill -9 $(pidof 'process_name')

Wenn Sie jedoch den genauen Namen des Prozesses nicht kennen, pgrep dies besser.

Wenn mehrere Prozesse mit demselben Namen ausgeführt werden und Sie den ersten beenden möchten, gehen Sie wie folgt vor:

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

Beachten Sie auch, dass Sie die Option -i wie in grep hinzufügen können, wenn Sie sich Sorgen über die Groß- und Kleinschreibung machen. Zum Beispiel:

kill -9 $(pgrep -fi chrome)

Weitere Infos zu Signalen und pgrep unter man 7 signaloder man signalundman pgrep

Rakib Fiha
quelle
5

Sie können es mit awk und backtics tun

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

$ 2 in awk druckt Spalte 2 und das Backtics führt die gedruckte Anweisung aus.

Eine viel sauberere Lösung wäre jedoch, dass der Python-Prozess seine Prozess-ID in / var / run speichert und Sie diese Datei dann einfach lesen und beenden können.

Alexander Kjäll
quelle
Beenden Sie dann nicht beide Prozesse 5124 und 5373? Ich denke das ist kein Problem.
Orjanp
Es sollte kein Problem sein, aber Sie können jederzeit einen weiteren Grep hinzufügen, um den Grep-Prozess auszuschließen: "grep -v grep" zwischen grep und awk
Alexander Kjäll
Getestet mit einem leicht modifizierten Befehl. Aber es hat den Prozess nicht beendet, sondern nur kill <pid> gedruckt. ps auxf | grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}'
Orjanp
Nur erforderlich, um die gedruckte "kill" $ 2-Anweisung gegen ein System auszutauschen ("kill" $ 2). Dann funktioniert es. :)
Orjanp
5

Meine Aufgabe war es, alles zu töten, was mit regulärem Ausdruck übereinstimmt, der sich in einem bestimmten Verzeichnis befindet (nach Selentests wurde nicht alles gestoppt). Das hat bei mir funktioniert:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done
Serge
quelle
Die -9Option killist vielleicht zu aggressiv. Es erlaubt ihnen nicht, ihre Ressourcen freizugeben.
Birei
Nett! Der einzige, der die Tatsache berücksichtigt, dass es möglicherweise mehr als einen Matching-Prozess gibt! Ein kleiner Hinweis: Vielleicht möchten Sie den Pipes ein "grep -v grep" oder ähnliches hinzufügen, um sicherzustellen, dass der grep-Prozess selbst nicht in Ihrer Prozessliste angezeigt wird.
Brad Parks
killAkzeptiert mehrere Prozesse, sodass die Schleife grundsätzlich unbrauchbar ist. und wie an anderer Stelle auf dieser Seite erwähnt, sollten Sie nicht verwenden, es kill -9sei denn, Sie wissen, dass der Prozess nicht nur darauf reagiert kill.
Tripleee
-9 entfernen ist keine große Sache, warum abstimmen. Sie sollten die Antwort besser bearbeiten.
Serge
5

So beenden Sie den Prozess anhand eines Schlüsselworts midori:

kill -SIGTERM $(pgrep -i midori)

l3v1ath4n
quelle
3

Eine Methode, die nur awk(und ps) verwendet:

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

Durch die Verwendung von String-Gleichheitstests verhindere ich, dass dieser Prozess selbst abgeglichen wird.

schot
quelle
Aus irgendeinem Grund bekomme ich keinen Treffer auf "python csp_build.py". Aber "Python" allein trifft.
Orjanp
3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
Vijay
quelle
Kann aufgrund des Tageslimits nicht +1 sein, aber die Verwendung psmit -oOption lohnt sich.
P Shved
ps gib mir nicht viel. [~] $ ps PID TTY TIME CMD 6365 Punkte / 6 00:00:00 ps 29112 Punkte / 6 00:00:00 Bash
Orjanp
3

Gib -f zu pkill

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

Der genaue Pfad der .py-Datei ist

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

Ich fing an, so etwas zu benutzen:

kill $(pgrep 'python csp_build.py')
Nathanael
quelle
1

Das Töten unserer eigenen Prozesse, die von einer gemeinsamen PPID aus gestartet wurden, ist ziemlich häufig. Der mit der –PFlagge verbundene Pkill ist für mich ein Gewinner. Beispiel: Verwenden von @ 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
quelle
1

Sie brauchen den Benutzerschalter nicht für ps.

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

In einigen Fällen möchte ich Prozesse gleichzeitig wie folgt beenden:

➜ ~ Schlaf 1000 &
[1] 25410
➜ ~ Schlaf 1000 &
[2] 25415
➜ ~ Schlaf 1000 &
[3] 25421
➜ ~ pidof Schlaf
25421 25415 25410
Kill ~ töte `pidof sleep`
[2] - 25415 beendete den Schlaf 1000                                                             
[1] - 25410 hat den Schlaf 1000 beendet
[3] + 25421 hat den Schlaf 1000 beendet

Aber ich denke, es ist in Ihrem Fall ein wenig unangemessen. (Möglicherweise laufen Python a, Python b, Python x ... im Hintergrund.)

kashu.org
quelle
1

Wenn pkill -f csp_build.pyder Prozess -9nicht abgebrochen wird, können Sie hinzufügen , um ein Kill-Signal zu senden, das nicht ignoriert wird. dhpkill -9 -f csp_build.py

yosemite_k
quelle
1

Die Lösung wäre, die Prozesse mit genauem Muster zu filtern, die PID zu analysieren und eine Argumentliste für die Ausführung von Kill-Prozessen zu erstellen:

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

Erklärung aus der Dokumentation:

Das Dienstprogramm ps zeigt eine Kopfzeile an, gefolgt von Zeilen mit Informationen zu allen Prozessen mit Steuerterminals.

-e Zeigt Informationen zu den Prozessen anderer Benutzer an, einschließlich dieser

-f Zeigt die UID, PID, übergeordnete PID, die letzte CPU-Auslastung und den Prozessstart an

Das Dienstprogramm grep durchsucht alle Eingabedateien und wählt die entsprechenden Zeilen aus

-e Muster, --regexp = Muster Geben Sie ein Muster an, das während der Suche nach der Eingabe verwendet wird: Eine Eingabezeile wird ausgewählt, wenn sie mit einem der angegebenen Muster übereinstimmt. Diese Option ist am nützlichsten, wenn mehrere -e-Optionen verwendet werden, um mehrere Muster anzugeben, oder wenn ein Muster mit einem Bindestrich (`- ') beginnt.

xargs - Argumentliste (n) erstellen und Dienstprogramm ausführen

töten - einen Prozess beenden oder signalisieren

Signal Nummer 9 - KILL (nicht fangbarer, nicht ignorierbarer Kill)

Beispiel :

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

Ich benutze dies, um Firefox zu töten, wenn das Skript zugeschlagen wird und die CPU aufgeschlagen wird :) Ersetzen Sie 'Firefox' durch die App, die Sie sterben möchten. Ich bin auf der Bash-Shell - OS X 10.9.3 Darwin.

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

mrhassell
quelle
Das Ersetzen grep Firefox | awk 'NR == 1 { next } ...'durch awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'spart nicht nur einen Prozess, sondern verbessert auch die Präzision. Es ist nicht schwer , um loszuwerden, sort | uniqin reinem Awk entweder (während natürlich uniq | sortnur falsch ist - es Duplikate verpassen , die nicht benachbart sind, und versteckt die Fehler durch unnötig die Sortier Ausgabe von uniq).
Tripleee
0

Ich benutze gkill processname, wobei gkill das folgende Skript ist:

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

HINWEIS: Prozesse, deren Befehlszeilen "grep" enthalten, werden NICHT beendet.

Kostyantyn
quelle
1
Wie die vielen, vielen anderen Neuerfindungen des Yak-Schuppens ist auch hier die nutzlose Verwendung vongrep und anderen gängigen Antimustern für Shell-Skripte durchsetzt.
Tripleee
-1

Der folgende Befehl ist praktisch:

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

z.B., 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

Wenn der Prozess immer noch nicht funktioniert, verwenden Sie die Erweiterung "-9", um Hardkill wie folgt auszuführen:

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

Ich hoffe, das hilft...!

Akshay Shah
quelle
-1

Finde und töte alle Prozesse in einer Zeile in Bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Gibt die Liste der laufenden Prozessdetails (uname, pid usw.) an, die dem Muster entsprechen. Die Ausgabeliste enthält diesen grepBefehl auch, der ihn durchsucht. Zum Töten müssen wir diesen grepBefehlsprozess ignorieren .
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- Durch Hinzufügen eines weiteren Grep mit -v 'grep'wird der aktuelle Grep-Prozess entfernt.
  • Verwenden awkSie dann nur die Prozess-ID.
  • Behalten Sie dann diesen Befehl im Inneren $(...)und übergeben Sie ihn an den killBefehl, um alle Prozesse abzubrechen.
Rashok
quelle
-1

Sie können den folgenden Befehl verwenden, um die PID des Befehls aufzulisten. Verwenden Sie top oder besser htop, um alle Prozesse unter Linux anzuzeigen. Hier möchte ich einen Prozess namens beenden

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

Und überprüfen Sie die PID. Es muss richtig sein. Um sie zu töten, benutze den Befehl kill.

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

ZB: - stammt aus der htop-Prozessliste.

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

Dies löst meine Probleme. Seien Sie immer bereit, den Prozess neu zu starten, wenn Sie versehentlich einen Prozess beenden.

Shijin
quelle