views:

1835

answers:

6

I need to see if a given process id is running, and it must work in either Java or JRuby (preferably a Ruby solution). It can be system dependent for Linux (specifically Debian and/or Ubuntu).

I already have the PID I am looking for, just need to see if it is currently running.


UPDATE:

Thanks for all the responses everyone! I appreciate it, however it's not QUITE what I'm looking for... I am hoping for something in a standard Ruby library (or Java, but preferably Ruby)... if no such library call exists, I will probably stick with the procfs solution I already have.

+2  A: 

From my answer to this question, I was thinking of just using procfs again, by checking if the given directory exists via File.exist? "/proc/#{pid}". This worked in jirb:

irb(main):001:0> File.exist? "/proc/5555"
=> false
irb(main):002:0> File.exist? "/proc/7677"
=> true

However, I would still prefer to use a method that specifically exists to detect if a process is running... like Process.exist?(pid)... which unfortunately doesn't exist that I've seen.

Mike Stone
A: 

I can't speak for JRuby, but in Java, the only way to check is if you launched the process from Java (in which case you would have an instance of Process that you could do things with).

Michael Myers
Thanks, but unfortunately the process is not a child process
Mike Stone
Well, it was worth a shot. :)
Michael Myers
A: 

You'll probably want to double check for the JVM that you're using. But if you send a SIGQUIT signal kill -3 I believe, (I don't have a terminal handy). That should generate a Javacore file which will have stack traces of the in use thread, check for JRuby packages in that file.

It shouldn't terminate or anything but as always be careful sending signals.

William
A: 

If you don't mind creating a whole new process then this lazy way should work:

def pid_exists? (pid)
    system "ps -p #{pid} > /dev/null"
    return $? == 0
end

For most variations of ps, it should return 0 on success and non-zero on error. The usual error with the usage above will be not finding the process with the given PID. The version of ps I have under Ubuntu returns 256 in this case.

You could also use Process.kill to send a signal of 0 to the process (signal 0 indicates if a signal may be sent), but that seems to only work if you own the process you're sending the signal to (or otherwise have permissions to send it signals).

Bribles
+2  A: 

Unix has a special feature of the kill system call around signal zero. Error checking is performed, but no signal is sent.

def pid_exists? (pid)
    system "kill -0 #{pid}"
    return $? == 0
end

One caveat: this won't detect processes with that pid that you don't have permission to signal.

Darron
The return statement is not necessary. The "system" call returns true/false to indicate if the command succeeded.
JesperE
+1  A: 

Darron's comment was spot on, but rather than calling the "kill" binary, you can just use Ruby's Process.kill method with the 0 signal:

#!/usr/bin/ruby 

pid = ARGV[0].to_i

begin
    Process.kill(0, pid)
    puts "#{pid} is running"
rescue Errno::EPERM                     # changed uid
    puts "No permission to query #{pid}!";
rescue Errno::ESRCH
    puts "#{pid} is NOT running.";      # or zombied
rescue
    puts "Unable to determine status for #{pid} : #{$!}"
end

[user@host user]$ ./is_running.rb 14302
14302 is running

[user@host user]$ ./is_running.rb 99999
99999 is NOT running.

[user@host user]$ ./is_running.rb 37
No permission to query 37!

[user@host user]$ sudo ./is_running.rb 37
37 is running

Reference: http://pleac.sourceforge.net/pleac_ruby/processmanagementetc.html

Jay