22

我想更改在 linux/unix top 命令中显示的 ruby​​ 进程的名称。我试过了

$0='miname'

方法,但它仅适用于 ps 命令,并且在顶部,该过程一直显示为“ruby”

4

7 回答 7

17

Dave Thomas 有一篇关于在 Rails 中执行此操作的有趣帖子。实际的进程名称更改代码没有任何特定的轨道。他使用这种$0='name'方法。当我按照他的步骤进行时,名称已更改为pstop

在帖子中,c如果您的 top 版本默认不显示命令的简短版本,他建议使用键盘命令。

于 2009-01-16T19:40:59.540 回答
10

Ruby 2.1为此引入了一种方法:Process.setproctitle

Process.setproctitle("My new title")
于 2015-03-12T17:58:51.423 回答
9

我认为 Ruby 没有内置的工具 ( setproctitle(3))。您可能应该尝试查看ruby​​-ffi并创建setproctitle(3).

编辑:我知道你有你的答案,但我想向你展示一些使用 ffi 的代码:

require "ffi"
#
module LibC
  extend FFI::Library

  attach_function :setproctitle, [:string, :varargs], :void
end

LibC.setproctitle("Ruby: executing %s", :string, $0)

不适用于 OS X,因为setproctitle(3)不存在,适用于 FreeBSD。

于 2009-01-16T15:07:17.173 回答
2

$0 = 'Foo' 方法有效——但许多版本的 top 将要求您使用 'c' 打开命令行模式。我们在 Rails 和 CentOS 中使用了这种方法。工作一种享受

于 2010-05-21T22:01:24.593 回答
2

我有一个类似的问题,通过将它放在机架中间件中而不是之前/之后模式,稍微更新了 Dave Thomas 帖子中的技术。

把它放在 lib/rack/set_process_title.rb 中:

# Set the process title to the URI being processed 
#- useful for debugging slow requests or those that get stuck
class Rack::SetProcessTitle
  def initialize(app)
    @app = app
  end
  def call(env)
    $0 = env['REQUEST_URI'][0..80]

    @status, @headers, @response = @app.call(env)

    $0 = env['REQUEST_URI'][0..80] + '*'

    [@status, @headers, @response]
  end
end

...这在 config/environment.rb 的末尾:

Rails.configuration.middleware.insert_after Rack::Lock, Rack::SetProcessTitle

博客文章中的更多文字:http: //blog.actbluetech.com/2011/06/set-your-process-name-in-top-and-ps.html

于 2011-06-09T18:34:52.787 回答
2

我知道 Keltia 已经发布了一些非常相似的东西,但是 Linux 没有 setproctitle(3)。Linux 从 2.6.9 版开始在 prctl() 中具有此功能。我使用了 Fiddle/DL,因为它们默认包含在 Ruby 中。

require("fiddle")

def set_process_name_linux(name)
    Fiddle::Function.new(
        Fiddle::Handle["prctl".freeze], [
            Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP,
            Fiddle::TYPE_LONG, Fiddle::TYPE_LONG,
            Fiddle::TYPE_LONG
        ], Fiddle::TYPE_INT
    ).call(15, name, 0, 0, 0)
end

def set_process_name_unknown(name)
    warn("No implementation for this OS.".freeze)
end

def set_process_name(name)
    case RUBY_PLATFORM.split("-".freeze)[1]
    when "linux".freeze
        set_process_name_linux(name)
    else
        set_process_name_unknown(name)
    end
end
于 2012-05-09T20:33:09.867 回答
0

来自@jessehz 的回答,以下代码在我的 linux X86_64 上完美运行。Ruby 1.9.3、2.0、2.1、2.2、2.3 已经过测试。

  1. 它将更改 ps top 命令中的输出。
  2. 它可以是 kill 或使用 pkill、pgrep、killall 发出信号。

完美的!

def set_process_name_linux(name)
  handle = defined?(DL::Handle) ? DL::Handle : Fiddle::Handle

  Fiddle::Function.new(
    handle['prctl'.freeze], [
      Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP,
      Fiddle::TYPE_LONG, Fiddle::TYPE_LONG,
      Fiddle::TYPE_LONG
    ], Fiddle::TYPE_INT
  ).call(15, name, 0, 0, 0)
  $PROGRAM_NAME = name
end
set_process_name_linux('dummy')
于 2016-03-15T16:19:25.870 回答