Я хотел бы изменить имя процесса ruby, который отображается в команде linux / unix top. Я пробовал
$0='miname'
подход, но он работает только с командой ps, и в верхней части процесс продолжает отображаться как "рубиновый"

Я не думаю, что 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.
У Дэйва Томаса был интересный Почта о том, как делать это в рельсах. В фактическом коде изменения имени процесса нет ничего конкретного. Он использует подход $0='name'. Когда я пошел по его стопам, название было изменено на ps и top.
В сообщении он предлагает использовать команду клавиатуры c, если ваша версия top не показывает краткую версию команды по умолчанию.
Я пробовал команду c keyboard, и она работает с машинами Linux. У верхней команды из Mac OS X, похоже, нет эквивалентной опции.
Ссылка мертва :( Не могли бы вы код показать?
web.archive.org спасает жизни: web.archive.org/web/20130415202502/http://…
И поэтому ссылку просто не даете :)
Метод $ 0 = 'Foo' работает, но многие версии top требуют, чтобы вы включили режим командной строки с помощью 'c'. Мы используем именно этот метод здесь с рельсами и CentOS. Работает удовольствие
Итак, как вы это делаете?
У меня была аналогичная проблема, я немного обновил технику из сообщения Дэйва Томаса, поместив ее в промежуточное программное обеспечение стойки, а не шаблон до / после.
# 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
Rails.configuration.middleware.insert_after Rack::Lock, Rack::SetProcessTitle
Больше слов в сообщении блога: http://blog.actbluetech.com/2011/06/set-your-process-name-in-top-and-ps.html
Я знаю, что Keltia уже опубликовала нечто очень похожее, но в Linux нет setproctitle (3). В Linux эта функция есть в prctl (), начиная с версии 2.6.9. Я использовал 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
В Ruby 2.2.3 DL устарел, необходимо изменить однострочный код. DL :: Handle необходимо изменить на Fiddle :: Handle для работы. этот ответ может отлично работать в Linux, он не меняет вывод ps, но может работать с pgrep.
Ruby 2.1 представил - метод Process.setproctitle для этой цели:
Process.setproctitle("My new title")
Я использую Ruby 2.2 в OSX, и Process.setproctitle действительно меняет то, что я вижу в ps -ef, тогда как $0 = "something" (или $PROGRAM_NAME = "something") - нет.
Я использую linux, этот ответ такой же, как `$ 0 = " My new title ", он просто меняет вывод ps, не может работать с pgrep или pkill.
Из ответа @jessehz следующий код отлично работает на моем Linux X86_64. Ruby 1.9.3, 2.0, 2.1, 2.2, 2.3 протестирован.
Идеально!
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')
Хотя это хороший пример FFI, используемая вами функция вообще не переносима. Кажется, это только freebsd и, возможно, другие разновидности bsd. Ни Linux (glibc), ни OS X, ни окон.