Ruby - 无法在守护进程中写入日志

4
通常我可以使用Logger编写日志:
//abc.rb
require 'logger'
logger = Logger.new('foo.log')

$./abc.rb

但在一个 守护进程 中,我遇到了权限错误:

//xyz.rb
require 'logger'
require 'daemons'

Daemons.run_proc('xyz') do
  logger = Logger.new('foo.log')
end

$./xyz.rb
/home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:599:in `initialize': Permission denied - foo.log (Errno::EACCES)
from /home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:599:in `open'
from /home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:599:in `create_logfile'
from /home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:594:in `open_logfile'
from /home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:549:in `initialize'
from /home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:314:in `new'
from /home/raincole/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/logger.rb:314:in `initialize'

我在同一目录下使用相同的身份运行了abc.rbxyz.rb,为什么一个可以登录而另一个不能?


守护进程设置有效用户ID吗? - Linuxios
1个回答

9
这是原因。来自Daemons文档
我已经用粗体标出了相关部分:

daemons在内部如何处理我的daemon?

从技术角度来看,当创建守护进程时,daemons会执行以下操作:

  1. 派生一个子进程(如果需要,退出父进程)
  2. 成为会话领导者(这将使程序与控制终端分离)。
  3. 派生另一个子进程并退出第一个子进程。这可以防止获取控制终端的潜在风险。
  4. 将当前工作目录更改为“/”。
  5. 清除文件创建掩码(将umask设置为0000)。
  6. 关闭文件描述符(重新打开STDOUT和STDERR以指向日志文件(如果可能))。
因此,在启动守护进程后,您应该将当前工作目录更改为要用于记录日志的目录(Dir.chdir),或使用绝对路径来记录日志文件。

我不推荐使用 chdir。守护进程(理想情况下所有应用程序)应始终使用绝对路径。访问相对路径通常是错误的根源。 - Kelvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接