Wie kann ich von Ruby überprüfen, ob ein Prozess mit einer bestimmten PID ausgeführt wird?

StackOverflow https://stackoverflow.com/questions/325082

  •  11-07-2019
  •  | 
  •  

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.

War es hilfreich?

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top