Wie kann ich von Ruby überprüfen, ob ein Prozess mit einer bestimmten PID ausgeführt wird?
Frage
Wenn es mehr als einen Weg gibt, listen Sie sie bitte auf. Ich kenne nur einen, aber ich frage mich, ob es einen saubereren, rubigen Weg gibt.
Lösung
Wenn es sich um einen Prozess handelt, den Sie "besitzen" erwarten (z. B. Sie verwenden diese, um eine PID für einen Prozess zu validieren, den Sie kontrollieren), können Sie SIG 0 einfach an ihn senden.
>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
from (irb):5:in `kill'
from (irb):5
>>
Andere Tipps
Der Unterschied zwischen dem Process.getpgid
und Process::kill
Ansätze scheinen das zu sein, was passiert, wenn die PID existiert, aber einem anderen Benutzer gehört. Process.getpgid
wird eine Antwort zurückgeben, Process::kill
wird eine Ausnahme auswerfen (Errno::EPERM)
.
Basierend darauf empfehle ich Process.getpgid
, wenn nur aus dem Grund, dass Sie zwei verschiedene Ausnahmen fangen müssen.
Hier ist der Code, den ich verwende:
begin
Process.getpgid( pid )
true
rescue Errno::ESRCH
false
end
@John T, @dustin: Eigentlich, Leute, ich habe den Prozess rdocs durchgesehen, und es sieht aus wie
Process.getpgid( pid )
ist ein weniger gewalttätiges Mittel, um dieselbe Technik anzuwenden.
Bei untergeordneten Prozessen verhalten sich andere Lösungen wie das Senden eines Signals nicht wie erwartet: Sie zeigen, dass der Prozess immer noch läuft, wenn er tatsächlich beendet ist.
Sie können verwenden Process.waitpid Wenn Sie einen Prozess überprüfen möchten, den Sie selbst hervorgebracht haben. Der Anruf wird nicht blockiert, wenn Sie die verwenden Process::WNOHANG
Flagge und nil
wird zurückgegeben, solange der Kinderprozess nicht beendet ist.
Beispiel:
pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid
Wenn die PID nicht zu einem Kinderprozess gehört, wird eine Ausnahme ausgelöst ((Errno::ECHILD: No child processes
).
Gleiches gilt für Process.waitpid2.
So habe ich es gemacht:
def alive?(pid)
!!Process.kill(0, pid) rescue false
end
Sie können versuchen zu verwenden
Process::kill 0, pid
Wenn PID die PID -Nummer ist, sollte es zurückgeben, wenn die PID ausgeführt wird.
Unter Linux können Sie viele Attribute für das Ausführen von Programmen mit dem Proc -Dateisystem erhalten:
File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
EIN *nix
-Nur der Ansatz wäre es, sich auszuschieben ps
und prüfen, ob a \n
(neue Linie) Der Abgrenzer existiert in der zurückgegebenen Zeichenfolge.
Beispiel IRB -Ausgabe
1.9.3p448 :067 > `ps -p 56718`
" PID TTY TIME CMD\n56718 ttys007 0:03.38 zeus slave: default_bundle \n"
Als Methode verpackt
def process?(pid)
!!`ps -p #{pid.to_i}`["\n"]
end
Ich habe dieses Problem schon einmal behandelt und gestern habe ich es in das "zusammengestellt" zusammengestellt "process_exists"Edelstein.
Es sendet das Nullsignal (0) mit der angegebenen PID an den Prozess, um zu überprüfen, ob es vorhanden ist. Es funktioniert auch, wenn der aktuelle Benutzer keine Berechtigungen hat, das Signal an den Empfangsprozess zu senden.
Verwendungszweck:
require 'process_exists'
pid = 12
pid_exists = Process.exists?(pid)