pkill kann Prozesse mit der übergeordneten Prozess-ID 1 nicht beenden

7

Ich möchte die folgenden Prozesse mit beenden

pkill "run_tcp_sender.sh"

oder

pkill -SIGKILL  "run_tcp_sender.sh"


    root     14320     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14323     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14325     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14327     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14328     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14330     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22

aber es ist nutzlos, die Prozesse bleiben dort, was ist mit meinem Befehl falsch?

Übrigens: Ich kann den folgenden Befehl verwenden, um das zu erreichen, was ich will

kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')
Misteryes
quelle
1
In welchem ​​Zustand befinden sich die Prozesse, wenn sie nicht getötet werden können? "Zustand D" -Prozesse müssen im Allgemeinen den Zustand D verlassen (wenn ihre E / A beendet ist), bevor sie ihre Signale betrachten, und Zustand Z-Prozesse können nicht beendet werden, egal was passiert (außer wenn der Elternteil das Kind oder den Administrator erntet) Neustart der Maschine). Ich denke, wenn Sie einen anderen Befehl verwenden, tun Sie möglicherweise für eine Weile etwas anderes, und die Prozesse ändern Ihren Status.
Bratchley
2
Gibt pgrep "run_tcp_sender.sh"die Liste der Prozesse zurück, die Sie beenden möchten, oder gibt sie nur eine leere Liste zurück, da alle Prozesse als aufgelistet sind bash run_tcp_sender.sh ...?
Jonathan Callen

Antworten:

18

pkillStandardmäßig sendet das SIGTERMSignal an Prozesse zum Stoppen. Hier ist eine Liste der Signale, die Sie an einen Prozess senden können. Sie können sie normalerweise nach Name oder Nummer senden:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

Sie senden also Signal Nr. 15. Wenn die Prozesse nicht auf dieses Signal reagieren, müssen Sie möglicherweise Signal Nr. 9 verwenden pkill -SIGKILL.

Aus der Manpage von pkill :

-Signal

  Defines the signal to send to each matched process.  Either the
  numeric  or  the symbolic signal name can be used.  (pkill only.)

Probleme mit pkill

Das OP erwähnte, dass es ihm nicht gelungen sei, pkill -SIGKILL "run_tcp"zur Arbeit zu kommen. Wir dachten zunächst, dass das Problem damit zu tun hat, sich pkillmöglicherweise selbst zu töten, bevor alle "run_tcp" -Prozesse beendet wurden.

Aber das war angesichts einer Fußnote auf der pkillManpage schwer zu akzeptieren :

Der laufende pgrep- oder pkill-Prozess meldet sich niemals als Übereinstimmung.

Darüber hinaus hat @Gilles einen Kommentar hinterlassen, der im Grunde dasselbe sagt, was sich pkilleinfach nicht selbst tötet. Dann gab er uns einen ziemlich großen Hinweis darauf, was tatsächlich vor sich ging.

Hier ist ein Beispiel, das zeigt, was dem OP und mir gefehlt hat:

Schritt 1 - Erstellen Sie ein sleepy.bash-Skript

#!/bin/bash

sleep 10000

Schritt 2 - Laden Sie einige falsche Schlafaufgaben

$ for i in `seq 1 5`;do bash sleepy.bash & done
[1] 12703
[2] 12704
[3] 12705
[4] 12706
[5] 12707

Schritt 3 - Überprüfen Sie die laufenden Aufgaben

$ ps -eaf|egrep "sleep 10000|sleepy"
saml     12703 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12704 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12705 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12706 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12707 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12708 12704  0 21:48 pts/16   00:00:00 sleep 10000
saml     12709 12707  0 21:48 pts/16   00:00:00 sleep 10000
saml     12710 12705  0 21:48 pts/16   00:00:00 sleep 10000
saml     12711 12703  0 21:48 pts/16   00:00:00 sleep 10000
saml     12712 12706  0 21:48 pts/16   00:00:00 sleep 10000

Schritt 4 - versuchen Sie es mit meinem Pkill

$ pkill -SIGTERM sleepy.bash

Schritt 5 - Was ist passiert?

Wenn pswir den Befehl von oben ausführen, sehen wir, dass keiner der Prozesse abgebrochen wurde, genau wie das OPs-Problem. Was ist los?

Es stellt sich heraus, dass dies ein Problem ist, wie wir versucht haben, davon Gebrauch zu machen pkill. Der Befehl:

pkill -SIGTERM "sleepy.bash"

suchte nach einem Prozess namens "sleepy.bash" . Nun, es gibt keine Prozesse mit diesem Namen. Es gibt jedoch Prozesse mit dem Namen "bash sleepy.bash" . Also pkillsuchte ich nach Prozessen, um zu töten und keine zu finden und dann zu beenden.

Wenn wir also das, pkillwas wir verwenden, leicht daran anpassen :

$ pkill -SIGTERM -f "sleepy.bash"
[1]   Terminated              bash sleepy.bash
[2]   Terminated              bash sleepy.bash
[3]   Terminated              bash sleepy.bash
[4]-  Terminated              bash sleepy.bash
[5]+  Terminated              bash sleepy.bash

Jetzt bekommen wir den Effekt, den wir gesucht haben. Was ist der Unterschied? Wir haben den -fSchalter verwendet, zu pkilldem pkillder gesamte Befehlszeilenpfad verwendet wird, wenn nur der Prozessname abgeglichen wird.

von pkill man page

-f      The pattern is normally only matched against the process name.  
        When  -f  is  set, the full command line is used.

Alternative Methoden

töten, ps

Diese Methode ist ziemlich ausführlich, macht aber auch den Job:

kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')

pgrep w / pkill & killall

Sie können entweder pgrepeine Liste von PIDs eingeben pkilloder killallstattdessen verwenden.

Beispiele

# pgrep solution
$ pgrep "run_tcp" | pkill -SIGKILL

# killall
killall -SIGKILL -r run_tcp

Verweise

slm
quelle
Warum funktioniert SIGTERM hier nicht?
Misteryes
Ich bin mir nicht sicher, ob die Anwendung sich selbst herunterfahren soll, aber sie reagiert nicht. Das SIGKILL ist das Betriebssystem, das den Prozess zerstört, der ein wenig schwer zu bedienen ist. Lassen Sie die Anwendung lieber selbst schließen, wenn dies möglich ist.
slm
pkill -SIGKILL ist wieder nutzlos! Ich kann nur kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')zum Töten verwenden, seltsam! wissen Sie, warum? danke
misteryes
Nein, pkilltötet sich nicht selbst und nein, es geht nicht darum, welches Signal gesendet wird. Es wird kein Signal gesendet, da es keinen Prozess mit diesem Namen gibt.
Gilles 'SO - hör auf böse zu sein'
@slm Siehe meine Antwort
Gilles 'SO- hör auf böse zu sein'
5

Dies hängt nicht mit der übergeordneten Prozess-ID zusammen. Das Problem ist einfach, dass Sie alle laufenden Prozesse beenden run_tcp_sender.sh, aber keine solchen Prozesse haben - die Prozesse, an denen Sie interessiert sind, werden ausgeführt bash.

Sie können pkilldie Übereinstimmung in der gesamten Befehlszeile anweisen :

pkill -f '^bash run_tcp_sender.sh'

Ein anderer Ansatz wäre, alle Prozesse zu beenden, bei denen das Skript geöffnet ist. Dies könnte Kollateralschäden verursachen, z. B. bei einem Editor, der gerade das Skript geöffnet hat.

fuser -k /path/to/run_tcp_sender.sh

Solange Sie das Skript nicht als root bearbeiten, kann das Problem behoben werden, indem nur die Prozesse von root beendet werden:

kill $(lsof -uroot /path/to/run_tcp_sender.sh)
Gilles 'SO - hör auf böse zu sein'
quelle
0

Versuchen Sie, den Prozess mit "Signal 9" zu beenden, ich meine verwenden

kill -9 PID

Normalerweise wird Signal 9 nicht zum Beenden der Datenbank-Engine empfohlen

Wenn der Prozess im Speicher verbleibt, geht ein E / A verloren oder der Prozess wartet auf den Abschluss der E / A.

Jalal Hajigholamali
quelle