一尘不染

在Ruby中使用双叉创建守护程序

linux

在Ruby中创建行为良好的Unix或Linux守护程序的正确方法是什么?

无论如何,行为良好的守护程序的定义是什么,如何用Ruby编写这样的程序?


阅读 227

收藏
2020-06-03

共1个答案

一尘不染

根据 UNIX环境 第13章的Stevens 高级编程 ,这是制作行为良好的Unix守护程序的过程:

  1. 分叉并有父出口。这使Shell或引导脚本认为命令已完成。此外,保证子进程不会成为进程组负责人(下一个setsid的先决条件)
  2. 呼叫setsid以创建一个新的会话。这做三件事:
    1. 该过程成为新会话的会话负责人
    2. 该流程成为新流程组的流程组负责人
    3. 该过程没有控制终端
  3. (可选)再次分叉并具有父出口。这确保守护程序不是会话领导者,也不能获取控制终端(在SVR4下)
  4. 更改当前工作目录,/以避免干扰安装和卸载
  5. 将文件模式创建掩码设置为000,以允许以后创建具有任何必需权限的文件。
  6. 继承自父关闭不需要的文件描述符(没有控制终端反正): ,stdoutstderrstdin

如今,有一个文件可以跟踪PID,Linux发行引导脚本经常使用该文件。确保写出孙子的PID,第二个fork的返回值(步骤3)或getpid()步骤3之后的值。

这是一个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
2020-06-03