28

Rubyで正常に動作するUnixまたはLinuxデーモンを作成する適切な方法は何ですか?

とにかく行儀の良いデーモンの定義は何ですか、そしてRubyでそのようなプログラムをどのように書くでしょうか?

4

2 に答える 2

54

UNIX環境でのStevensの高度なプログラミングの第13章によると、これは正常に動作するUnixデーモンを作成する手順です。

  1. フォークして親出口を持ちます。これにより、シェルまたはブートスクリプトはコマンドが完了したと見なします。また、子プロセスはプロセスグループリーダーではないことが保証されています(setsid nextの前提条件)
  2. setsid新しいセッションを作成するために呼び出します。これは3つのことを行います:
    1. プロセスは新しいセッションのセッションリーダーになります
    2. プロセスは、新しいプロセスグループのプロセスグループリーダーになります
    3. プロセスには制御端末がありません
  3. 必要に応じて、再度フォークして、親を終了します。これにより、デーモンがセッションリーダーではなく、制御端末(SVR4の下)を取得できないことが保証されます。
  4. 現在の作業ディレクトリを変更して/、マウントとアンマウントの干渉を回避します
  5. ファイルモード作成マスクを000に設定して、後で必要な権限を持つファイルを作成できるようにします。
  6. 親から継承された不要なファイル記述子を閉じます(とにかく制御端末はありません):stdout、、、。stderrstdin

現在、Linuxディストリビューションのブートスクリプトで頻繁に使用されるPIDを追跡するためのファイルがあります。2番目のフォークの戻り値(ステップ3)またはステップ3の後の値のいずれかで、孫のPIDを必ず書き出してくださいgetpid()

これはRubyの実装であり、ほとんどが本から翻訳されていますが、ダブルフォークとデーモンPIDの書き込みが含まれています。

# Example double-forking Unix daemon initializer.

raise 'Must run as root' if Process.euid != 0

raise 'First fork failed' if (pid = fork) == -1
exit unless pid.nil?

Process.setsid
raise 'Second fork failed' if (pid = fork) == -1
exit unless pid.nil?
puts "Daemon pid: #{Process.pid}" # Or save it somewhere, etc.

Dir.chdir '/'
File.umask 0000

STDIN.reopen '/dev/null'
STDOUT.reopen '/dev/null', 'a'
STDERR.reopen STDOUT
于 2009-11-16T05:54:07.487 に答える
6

ジェイソンの素晴らしい応答に続いて、私はここに完全な実装を書きました:

https://gist.github.com/1372491/b76b60fb1842bf0507f47869ab19ad50a045b214

ダブルフォークとpidのファイルへの書き込みに加えて、ロギングを実装しました。

もう1つの興味深い実装は、Unicornにあります。

https://github.com/defunkt/unicorn/blob/master/lib/unicorn/launcher.rb

于 2012-03-17T03:10:56.890 に答える