Was macht `kill -0 $ pid` in einem Shell-Skript?

Antworten:

136

Wenn Sie das Signal 0an eine bestimmte PIDPerson senden , wird nur überprüft, ob ein Prozess mit der angegebenen Funktion ausgeführt PIDwird, und Sie haben die Berechtigung, ein Signal an diese zu senden.

Weitere Informationen finden Sie auf den folgenden Seiten:

töten (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
töten (2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed; this 
can be used to check for the existence of a process ID or process group ID.
...
Dwalter
quelle
7
Der Speicherort dieser Informationen (falls überhaupt vorhanden) ist stark systemabhängig. Verwenden Sie auf neueren Debian-basierten Systemen man 2 killstattdessen.
Todd A. Jacobs
2
Beides man 1 killund man 2 killhatte es auf meinem Fedora 20 System. Es ist jedoch schwer zu erkennen, in diesen beiden Manpages vergraben.
Slm
Oder verlassen Sie sich stattdessen auf das Posix-Handbuch: If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid. pubs.opengroup.org/onlinepubs/009695399/functions/kill.html
Thomas Hughes
2
Ich fühle mich wie der Befehl man 2 killist außerhalb der 1. Änderung :)
JBaczuk
126

Dies ist eine gute Frage, weil ...

... kann es schwierig sein, Dokumentation zu diesem speziellen Signal zu finden. Ungeachtet dessen, was andere gesagt haben, ist die einzige Erwähnung dieses Signals man 1 killin Debian-basierten Systemen:

Besonders nützliche Signale sind HUP, INT, KILL, STOP, CONT und 0.

Nicht besonders hilfreich, besonders wenn Sie noch nicht wissen, was das Signal bewirkt. Es wird auch nicht in der Ausgabe von aufgeführt kill -l, sodass Sie nichts davon wissen, es sei denn, Sie wissen es bereits.

Wo finde ich es dokumentiert

Auf Debian- und Ubuntu-Systemen ist die Ausgabe von man 2 kill Teil:

Wenn sig 0 ist, wird kein Signal gesendet, aber die Fehlerprüfung wird trotzdem durchgeführt. Dies kann verwendet werden, um das Vorhandensein einer Prozess-ID oder einer Prozessgruppen-ID zu überprüfen.

Wofür es gut ist

Mit können Sie kill -0überprüfen, ob ein Prozess ausgeführt wird. Betrachten Sie diese Beispiele.

# Kill the process if it exists and accepts signals from
# the current user.
sleep 60 &
pid=$!
kill -0 $pid && kill $pid

# Check if a PID exists. When missing, this should result
# in output similar to:
#    bash: kill: (6228) - No such process
#    Exit status: 1
kill -0 $pid; echo "Exit status: $?"

Sie können auch kill -0bestimmen, ob der aktuelle Benutzer über Berechtigungen zum Signalisieren eines bestimmten Prozesses verfügt. Beispielsweise:

# See if you have permission to signal the process. If not,
# this should result in output similar to:
#     bash: kill: (15764) - Operation not permitted
#     Exit status: 1
sudo sleep 60 &
kill -0 $!; echo "Exit status: $?"
Todd A. Jacobs
quelle
Auf Mac und BSD ist es auch dokumentiert in kill(2) Hier ist der Ausschnitt:The kill() function sends the signal specified by sig to pid, a process or a group of processes. Typically, Sig will be one of the signals specified in sigaction(2). A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid.
Lukecampbell
8
Dies sollte die akzeptierte Antwort sein. Viel besser als der andere. Die Dokumentation zu Signal 0 ist schwer zu finden. Es ist in der killManpage vergraben : "Wenn sig 0 ist, wird kein Signal gesendet, aber es wird immer noch eine Fehlerprüfung durchgeführt."
Slm
6

Dieser Befehl prüft, ob der Prozess mit der PID in $ pid aktiv ist.

Fritz G. Mehner
quelle
1
Auf der Manpage heißt es: "Wenn sig 0 ist, wird kein Signal gesendet, aber die Fehlerprüfung wird weiterhin durchgeführt." Auf welche Fehlerprüfung beziehen wir uns hier?
Gjain
2
-1, da $pidmöglicherweise ein Prozess mit PID ausgeführt wird, Sie jedoch nicht die Berechtigung haben, ein Signal an ihn zu senden.
Dwalter
2
@dwalter: Wenn du keine Erlaubnis hast, bekommst du ein EPERM. Wenn es nicht existiert, erhalten Sie einen ESRCH. Das kill(1)gibt für jeden einen anderen Fehler aus. Sie können also feststellen, ob die PID aktiv ist, unabhängig davon, ob Sie zum Senden von Signalen berechtigt sind oder nicht. Darüber hinaus besteht die typische Verwendung von kill -0darin, festzustellen, ob die PID aktiv ist, auch wenn sie nicht immer korrekt verwendet wird. Ich würde sagen, diese Antwort ist richtig (abgesehen von der Schreibweise).
Camh
3
@camh: nein, der Rückgabewert von kill -0 $pidist in beiden Fällen gleich. Es wird zurückgegeben, 1sodass Sie nicht ohne Analyse der Ausgabe sagen können, killob der Prozess ausgeführt wird oder nicht, wenn Sie nicht die Berechtigung haben, ein Signal an ihn zu senden. BEARBEITEN: Ja, ich weiß, dass es die meiste Zeit verwendet wird, um zu überprüfen, ob ein Prozess aktiv ist, aber dies ist falsch, es sei denn, Sie können garantieren, dass Sie die Berechtigung zum Senden des Signals haben (z. B. root sein)
dwalter
2
@ Dwalter: Mein Punkt war, dass die Antwort richtig ist. Sie haben versucht, pedantisch zu sein und darauf hinzuweisen, dass es einen anderen Fehlerfall gab, aber ich sage Ihnen, dass die Antwort technisch auch diesen Fall abdeckt, da die killeingebaute Bash (die Frage ist markiert bash) die Art des Fehlers auf stderr und die Anzeige ausgibt eines Fehlers in seinem Rückkehrcode. Das heißt, "Dieser Befehl prüft, ob der Prozess mit der PID in $ pid aktiv ist" ist vollständig korrekt, wenn Sie die Ausgabe richtig interpretieren. [Ich hätte nicht kommentiert, wenn Sie nicht gesagt hätten, dass Sie der Antwort -1 gegeben haben. Ihr Kommentar ist ansonsten gültig].
Camh
6

Kill -0 $ pid dient dazu zu überprüfen, ob der Prozess mit pid vorhanden ist oder nicht.

Seien Sie vorsichtig, wenn Sie 'kill -0 $ pid' verwenden, um die Existenz des Prozesses zu überprüfen, da

  1. Sobald der beabsichtigte Prozess beendet ist, kann seine PID einem anderen neu erstellten Prozess zugewiesen werden. (Man kann also nicht so sicher sein, ob ein bestimmter Prozess aktiv ist oder nicht)

  2. Im Falle eines Zombie-Prozesses wartet das Kind darauf, dass die Eltern auf wait warten. Hier hält es die $ pid und gibt das positive Ergebnis, während dieser Prozess nicht läuft.

Sandeep_black
quelle
1

Kill -0 $ pid wird verwendet, um zu überprüfen, ob ein mit $ pid ausgeführter Prozess aktiv ist oder nicht. Dies kann jedoch schwierig sein, da die Prozess-ID neu zugewiesen werden kann, sobald ein Prozess beendet wird und ein neuer Prozess ausgeführt wird. Man kann killall -0 verwenden, um herauszufinden, ob ein bestimmter Prozess ausgeführt wird oder nicht.


quelle
0

Das Senden des EXITSignals oder 0an einen Prozess wird:

  1. Überprüfen Sie, ob ein Prozess vorhanden ist.
  2. Führen Sie verschiedene Fehlerprüfungen für den Prozess durch (PID, PGID usw.).
  3. stdoutBei Erfolg wird keine Ausgabe an gesendet.
  4. Senden Sie eine Fehlermeldung an, stderrwenn etwas nicht stimmt.
  5. Geben Sie ein falsches Positiv, wenn der Prozess nicht mehr funktioniert (z. B. Zombie).

Genauer gesagt wäre eine nützliche Funktion für Ihre Shell-Skripte:

function isProcess ()
{
    kill -s EXIT $1 2> /dev/null
}

Dies gibt stdoutbei Erfolg keinen Text zurück , sondern eine Fehlermeldung stderrbei Fehler (aber ich habe diese Fehlermeldung an weitergeleitet /dev/null).

Wenn Sie sich Sorgen über den Status eines nicht mehr existierenden / Zombie-Prozesses machen , müssen Sie diesen verwenden ps, vorzugsweise mit dem --no-headersSchalter.

#!/bin/ksh

function trim ()
{
    echo -n "$1" | tr -d [:space:]
}

function getProcessStatus ()
{
    trim $(ps -p $1 -o stat --no-headers)
}

function isZombie ()
{
    typeset processStatus=$(getProcessStatus $1)

    [[ "$processStatus" == "Z" ]]
    return $?
}
Anthony Rutledge
quelle