Ich schreibe ein Perl-Skript, das Protokolldateien analysiert, um PIDs zu sammeln, und dann prüft, ob diese PID ausgeführt wird. Ich versuche, mir den besten Weg zu überlegen, um diesen Scheck zu machen. Offensichtlich könnte ich etwas machen wie:
system("ps $pid > /dev/null") && print "Not running\n";
Ich würde es jedoch vorziehen, den Systemaufruf nach Möglichkeit zu vermeiden. Ich dachte daher, ich könnte das /proc
Dateisystem verwenden (Portabilität ist kein Problem, dies wird immer auf einem Linux-System ausgeführt). Beispielsweise:
if(! -d "/proc/$pid"){
print "Not running\n";
}
Ist das sicher? Kann ich immer davon ausgehen, dass /proc/$pid/
die zugehörige PID nicht ausgeführt wird , wenn kein Verzeichnis vorhanden ist? Ich gehe davon aus, dass AFAIK ps
selbst /proc
sowieso seine Informationen erhält, aber da es sich um Seriencode handelt, möchte ich sicher gehen.
Kann es also Fälle geben, in denen ein laufender Prozess kein /proc/PID
Verzeichnis hat oder in denen ein /proc/PID
Verzeichnis existiert und der Prozess nicht läuft? Gibt es einen Grund, das Parsen der ps
Überprüfung auf das Vorhandensein des Verzeichnisses vorzuziehen ?
quelle
kill
Funktion mit dem Signal 0, die keine Tötung durchführt, aber angibt, ob Sie dies tun könnten (dh Sie benötigen die Erlaubnis, diesen Prozess zu signalisieren).kill -0
der besten) Methode nur angezeigt wird, ob ein Prozess mit der angegebenen PID ausgeführt wird . Es sagt Ihnen nicht, ob der Prozess eine Millisekunde später noch ausgeführt wird, und es sagt Ihnen nicht, ob der Prozess derjenige ist, an dem Sie interessiert sind, oder ein nicht verwandter Prozess, dem nach dem Abbruch des interessanten Prozesses dieselbe PID zugewiesen wurde . Es ist fast immer ein Fehler zu testen, ob eine bestimmte PID ausgeführt wird : Es gibt nur sehr wenige Umstände, unter denen dies nicht für Rennbedingungen anfällig ist.Antworten:
Die Perl-Funktion
kill(0,$pid)
kann verwendet werden.Wenn der Rückkehrcode 1 ist, ist die PID vorhanden und Sie können ein Signal an sie senden.
Wenn der Rückkehrcode 0 ist, müssen Sie $! Überprüfen. Es kann EPERM (Berechtigung verweigert) sein, was bedeutet, dass der Prozess existiert, oder ESRCH, in welchem Fall der Prozess nicht existiert.
Wenn Ihr Überprüfungscode so läuft
root
, können Sie dies vereinfachen, indem Sie nur den Rückkehrcode von kill überprüfen. 0 => Fehler, 1 => okBeispielsweise:
Dies kann zu einer einfachen Funktion gemacht werden
quelle
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
oder ähnliches brauchte . IhreErrno
Lösung gefällt mir allerdings besser, danke. Während ich wahrscheinlich damit anfangen werde, werde ich eine Weile warten, falls jemand die zugrunde liegende Linux-Frage beantworten kann./proc
gemountet ist, ist jede im Namespace sichtbare PID vorhanden, sodass Ihr-d /proc/$pid
Test funktionieren würde. Dabei wird jedoch nicht über systemeigene Systemaufrufe auf das Dateisystem zugegriffen.system
Aufruf" verstanden haben - also einen Aufruf dersystem
Funktion selbst, keinen "Systemaufruf" . Letzteres können Sie nicht vermeiden, Ersteres jedoch mit Sicherheit. Macht jetzt Sinn!/proc/PID
kill 0
/proc
/proc
ps
top
lsof
), und ich glaube, dass es keine Garantie dafür gibt, dass es existieren wird (dh, es wird von POSIX nicht benötigt). Und wenn das System nicht komplett abgespritzt ist,kill
funktioniert es./proc
erfordert das Lesen des Stammverzeichnisses, um das/proc
Dateisystem zu finden . Dies gilt für jeden Versuch den Zugriff auf alle von einer absoluten Pfaddatei, einschließlich solcher Dinge in/bin
,/etc
und/dev
. Dies geschieht so oft, dass das Stammverzeichnis sicher für die gesamte Lebensdauer (Betriebszeit) des Systems im Arbeitsspeicher zwischengespeichert wird. Daher kann dieser Schritt ohne Datenträger-E / A ausgeführt werden. Und sobald Sie die Inode von haben/proc
, ist alles andere, was passiert, in Erinnerung./proc
? Mitstat
,open
,readdir
, usw., die native System wie jedes Bit so viel fordertkill
.Die Frage spricht von einem laufenden Prozess. Dies ist eine glatte Phrase. Wenn Sie tatsächlich testen wollen , ob der Prozess ausgeführt wird (dh in der Task - Liste, vielleicht den aktuellen Prozess auf einigen CPU, nicht schlafen, warten oder gestoppt), müssen Sie möglicherweise eine tun und lesen Sie die Ausgabe oder Blick auf . Aber ich sehe keinen Hinweis in Ihrer Frage oder Ihren Kommentaren, dass Sie sich damit befassen.
ps PID
/proc/PID/stat
Der Elefant im Raum ist jedoch, dass es schwierig sein kann , einen Zombie- 2- Prozess von einem lebendigen und gesunden Prozess zu unterscheiden.
kill 0
arbeitet an einem Zombie und existiert. Sie können Zombies mit den Techniken identifizieren, die im vorherigen Absatz aufgeführt sind ( die Ausgabe ausführen und lesen oder anschauen ). Meine sehr schnell & casual (dh nicht sehr gründlich) Tests legen nahe , dass Sie dies auch durch ein Tun tun können , oder auf , oder - diese auf Zombies scheitern. (Sie schlagen jedoch auch bei Prozessen fehl, die Sie nicht besitzen.)/proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1 Wenn die Option
-f
( f orce) nicht funktioniert, versuchen Sie es mit-l
( l azy).2 dh ein Prozess, der beendet / gestorben / beendet wurde, dessen Eltern noch nicht a
wait
.quelle
kill(2)
Manpage direkt das Verhalten anzeigt, auf das Sie hingewiesen haben, aber dieperlfunc
Manpage tut es. Ich werde Michael Kerrisk eine E-Mail senden, um zu erfahren, was er zu der Manpage des Systems zu sagen hat.kill(2)
bezüglich der Berechtigungen zum "Senden" von Signal 0 zukill(2)
Manpage geändert (ich sehe sie noch nicht online): "Wenn sig 0 ist, wird kein Signal gesendet, aber es werden noch Existenz- und Berechtigungsprüfungen durchgeführt. Dies kann verwendet werden, um die Existenz von a zu überprüfen Prozess-ID oder Prozessgruppen-ID, die der Anrufer signalisieren darf. "