Hoe kan ik vanuit Ruby controleren of een proces met een bepaalde pid draait?

Als er meer dan één manier is, vermeld deze dan. Ik ken er maar één, maar ik vraag me af of er een schonere, in-Ruby manier is.


Antwoord 1, autoriteit 100%

Het verschil tussen de Process.getpgiden Process::killbenaderingen lijkt te zijn wat er gebeurt wanneer de pid bestaat maar eigendom is van een andere gebruiker. Process.getpgidretourneert een antwoord, Process::killgenereert een uitzondering (Errno::EPERM).

Op basis daarvan raad ik Process.getpgidaan, al was het maar om de reden dat het je bespaart dat je twee verschillende uitzonderingen moet opvangen.

Dit is de code die ik gebruik:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end

Antwoord 2, autoriteit 85%

Als het een proces is waarvan u verwacht dat het “bezit” (u gebruikt dit bijvoorbeeld om een ​​pid te valideren voor een proces dat u beheert), kunt u er gewoon een sig 0 naar sturen.

>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
    from (irb):5:in `kill'
    from (irb):5
>> 

Antwoord 3, autoriteit 74%

@John T, @Dustin: Eigenlijk, jongens, ik heb de Process rdocs doorgenomen, en het lijkt erop dat

Process.getpgid( pid )

is een minder gewelddadige manier om dezelfde techniek toe te passen.


Antwoord 4, autoriteit 50%

Voor onderliggende processen zullen andere oplossingen, zoals het verzenden van een signaal, zich niet gedragen zoals verwacht: ze geven aan dat het proces nog loopt wanneer het daadwerkelijk is afgesloten.

Je kunt Process.waitpidals je een proces wilt controleren dat je zelf hebt voortgebracht. De aanroep wordt niet geblokkeerd als u de vlag Process::WNOHANGgebruikt en nilwordt geretourneerd zolang het onderliggende proces niet is afgesloten.

Voorbeeld:

pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid

Als de pid niet tot een onderliggend proces behoort, wordt een uitzondering gegenereerd (Errno::ECHILD: No child processes).

Hetzelfde geldt voor Process.waitpid2.


Antwoord 5, autoriteit 10%

Dit is hoe ik het heb gedaan:

def alive?(pid)
  !!Process.kill(0, pid) rescue false
end

Antwoord 6, autoriteit 8%

Je kunt proberen met

Process::kill 0, pid

waar pid het pid-nummer is, als de pid actief is, zou het 1 moeten retourneren.


Antwoord 7, autoriteit 6%

Onder Linux kun je veel attributen van een draaiend programma verkrijgen met behulp van het proc-bestandssysteem:

File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")

Antwoord 8

Een *nix-aanpak zou zijn om uit te schakelen naar psen te controleren of er een \n(nieuwe regel) scheidingsteken bestaat in de geretourneerde tekenreeks.

Voorbeeld IRB-uitvoer

1.9.3p448 :067 > `ps -p 56718`                                                          
"  PID TTY           TIME CMD\n56718 ttys007    0:03.38 zeus slave: default_bundle   \n"

Verpakt als een methode

def process?(pid)  
  !!`ps -p #{pid.to_i}`["\n"]
end

Antwoord 9

Ik heb dit probleem eerder behandeld en gisteren heb ik het gecompileerd in de “process_exists” gem.

Het stuurt het nulsignaal (0) naar het proces met de gegeven pid om te controleren of het bestaat. Het werkt zelfs als de huidige gebruiker geen toestemming heeft om het signaal naar het ontvangende proces te sturen.

Gebruik:

require 'process_exists'
pid = 12
pid_exists = Process.exists?(pid)

Other episodes