How can I check from Ruby whether a process with a certain pid is running?

RubyProcessPid

Ruby Problem Overview


If there is more than one way, please list them. I only know of one, but I'm wondering if there is a cleaner, in-Ruby way.

Ruby Solutions


Solution 1 - Ruby

The difference between the Process.getpgid and Process::kill approaches seems to be what happens when the pid exists but is owned by another user. Process.getpgid will return an answer, Process::kill will throw an exception (Errno::EPERM).

Based on that, I recommend Process.getpgid, if just for the reason that it saves you from having to catch two different exceptions.

Here's the code I use:

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

Solution 2 - Ruby

If it's a process you expect to "own" (e.g. you're using this to validate a pid for a process you control), you can just send sig 0 to it.

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

Solution 3 - Ruby

@John T, @Dustin: Actually, guys, I perused the Process rdocs, and it looks like

Process.getpgid( pid )

is a less violent means of applying the same technique.

Solution 4 - Ruby

For child processes, other solutions like sending a signal won't behave as expected: they will indicate that the process is still running when it actually exited.

You can use Process.waitpid if you want to check on a process that you spawned yourself. The call won't block if you're using the Process::WNOHANG flag and nil is going to be returned as long as the child process didn't exit.

Example:

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

If the pid doesn't belong to a child process, an exception will be thrown (Errno::ECHILD: No child processes).

The same applies to Process.waitpid2.

Solution 5 - Ruby

This is how I've been doing it:

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

Solution 6 - Ruby

You can try using

Process::kill 0, pid

where pid is the pid number, if the pid is running it should return 1.

Solution 7 - Ruby

Under Linux you can obtain a lot of attributes of running programm using proc filesystem:

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

Solution 8 - Ruby

A *nix-only approach would be to shell-out to ps and check if a \n (new line) delimiter exists in the returned string.

Example IRB Output

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

Packaged as a Method

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

Solution 9 - Ruby

I've dealt with this problem before and yesterday I compiled it into the "process_exists" gem.

It sends the null signal (0) to the process with the given pid to check if it exists. It works even if the current user does not have permissions to send the signal to the receiving process.

Usage:

require 'process_exists'

pid = 12
pid_exists = Process.exists?(pid)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPistosView Question on Stackoverflow
Solution 1 - RubytonystubblebineView Answer on Stackoverflow
Solution 2 - RubyDustinView Answer on Stackoverflow
Solution 3 - RubyPistosView Answer on Stackoverflow
Solution 4 - RubybaluView Answer on Stackoverflow
Solution 5 - RubykomatsuView Answer on Stackoverflow
Solution 6 - RubyJohn TView Answer on Stackoverflow
Solution 7 - RubyamenzhinskyView Answer on Stackoverflow
Solution 8 - RubyDaniel DoezemaView Answer on Stackoverflow
Solution 9 - RubyWilson SilvaView Answer on Stackoverflow