在 Ruby 中创建行为良好的 Unix 或 Linux 守护程序的正确方法是什么?
无论如何,行为良好的守护进程的定义是什么,如何用 Ruby 编写这样的程序?
根据 Stevens 的UNIX 环境中的高级编程第 13 章,这是制作表现良好的 Unix 守护进程的过程:
setsid
以创建新会话。这做了三件事:
/
避免干扰挂载和卸载stdout
、stderr
和stdin
.现在有一个文件可以跟踪被 Linux 发行版引导脚本大量使用的 PID。一定要写出孙子的PID,要么是第二个fork(第3步)的返回值,要么是第3getpid()
步之后的值。
这是一个 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
继 Jason 的精彩回应之后,我在这里编写了一个更完整的实现:
https://gist.github.com/1372491/b76b60fb1842bf0507f47869ab19ad50a045b214
除了双叉和将 pid 写入文件之外,我还实现了日志记录。
另一个有趣的实现是在 Unicorn 中:
https://github.com/defunkt/unicorn/blob/master/lib/unicorn/launcher.rb