2

我需要查看给定的进程 ID 是否正在运行,并且它必须在 Java 或 JRuby(最好是 Ruby 解决方案)中工作。它可以依赖于 Linux(特别是 Debian 和/或 Ubuntu)的系统。

我已经有了我要查找的 PID,只需要查看它当前是否正在运行。


更新:

感谢大家的所有回复!我很感激,但它不是我正在寻找的东西......我希望在标准 Ruby 库(或 Java,但最好是 Ruby)中找到一些东西......如果不存在这样的库调用,我可能会坚持我已经拥有的 procfs 解决方案。

4

7 回答 7

11

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

于 2008-10-14T09:51:51.017 回答
5

Unix 在信号零附近有一个特殊的 kill 系统调用功能。执行错误检查,但不发送信号。

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

一个警告:这不会检测您无权发出信号的具有该 pid 的进程。

于 2008-09-26T20:23:37.557 回答
2

根据我对这个问题的回答,我正在考虑再次使用 procfs,通过 File.exist 检查给定目录是否存在?“/proc/#{pid}”。这在 jirb 中有效:

irb(main):001:0> File.exist? “/proc/5555”
=> 假的
irb(main):002:0> File.exist? “/proc/7677”
=> 真

但是,我仍然更喜欢使用一种专门存在的方法来检测进程是否正在运行......比如 Process.exist?(pid)...... 不幸的是,我见过它不存在。

于 2008-09-26T18:34:27.743 回答
0

如果您不介意创建一个全新的流程,那么这种懒惰的方式应该可行:

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

对于ps的大多数变体,它应该在成功时返回 0,在错误时返回非零。上述用法的常见错误是找不到具有给定 PID 的进程。在这种情况下,我在 Ubuntu 下的ps版本返回 256。

您也可以使用 Process.kill 向进程发送信号 0(信号 0 表示是否可以发送信号),但这似乎只有在您拥有将信号发送到的进程(或以其他方式拥有)时才有效发送信号的权限)。

于 2008-09-26T20:10:45.843 回答
0

我不能代表 JRuby,但在 Java 中,唯一的检查方法是检查您是否从 Java 启动了进程(在这种情况下,您将拥有一个可以使用的Process实例)。

于 2008-09-26T18:40:34.997 回答
0

您可能需要仔细检查您正在使用的 JVM。但是如果你发送一个SIGQUIT信号 kill -3 我相信,(我手边没有终端)。这应该会生成一个 Javacore 文件,该文件将具有正在使用的线程的堆栈跟踪,检查该文件中的 JRuby 包。

它不应该终止或任何东西,但一如既往地小心发送信号。

于 2008-09-26T19:00:37.883 回答
0

jps您可以使用java 安装附带的命令行工具。jps 列出了一个用户的所有 java 进程。

例如

>jps -l
5960 org.jruby.Main
2124 org.jruby.Main
5376 org.jruby.Main
4428 sun.tools.jps.Jps

或者,如果您需要将结果放入脚本中,您可以使用 %x[..]:

>> result = %x[jps -l]
=> "5960 org.jruby.Main\n2264 sun.tools.jps.Jps\n2124 org.jruby.Main\n5376 org.jruby.Main\n"
>> p result
"5960 org.jruby.Main\n2264 sun.tools.jps.Jps\n2124 org.jruby.Main\n5376 org.jruby.Main\n"
=> nil
于 2010-11-25T16:20:46.350 回答