【问题标题】:How can I determine if a different process id is running using Java or JRuby on Linux?如何确定是否在 Linux 上使用 Java 或 JRuby 运行了不同的进程 ID?
【发布时间】:2010-09-13 13:25:34
【问题描述】:

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

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


更新:

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

【问题讨论】:

  • mike,您的问题的标题暗示您想知道给定的 PID 本身是否是 Java|JRuby 进程。问题的其余部分建议您只打算使用 Java|JRuby 来了解给定 PID 的退出情况。请澄清!

标签: java ruby linux jruby pid


【解决方案1】:

Darron's comment 是正确的,但您可以使用 Ruby 的 Process.kill 方法和 0 信号,而不是调用“kill”二进制文件:

#!/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 用户]$ ./is_running.rb 14302
14302正在运行

[user@host 用户]$ ./is_running.rb 99999
99999 没有运行。

[user@host 用户]$ ./is_running.rb 37
无权查询 37!

[user@host 用户]$ sudo ./is_running.rb 37
37 正在运行

参考:http://pleac.sourceforge.net/pleac_ruby/processmanagementetc.html

【讨论】:

    【解决方案2】:

    Unix 有一个特殊的功能,即围绕信号零调用 kill 系统。执行错误检查,但未发送任何信号。

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

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

    【讨论】:

    • return 语句不是必须的。 “系统”调用返回真/假以指示命令是否成功。
    【解决方案3】:

    来自my answer to this question,我想再次使用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)... 不幸的是,我见过的这种方法不存在。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 谢谢,可惜该进程不是子进程
      • 嗯,值得一试。 :)
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

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

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

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

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

        【讨论】:

          【解决方案7】:

          您可以使用 java 安装附带的命令行工具 jps。 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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-09-17
            • 2012-02-25
            • 1970-01-01
            • 2023-03-09
            • 2012-01-15
            • 1970-01-01
            • 1970-01-01
            • 2016-02-20
            相关资源
            最近更新 更多