如何在root拥有的Ruby中创建文本文件?

时间:2018-08-10 09:04:33

标签: ruby file unix

在Ruby中,使用File.write作为当前用户创建文本文件非常容易,但是如果我希望该文件归root用户拥有,它将变得更加复杂。

我意识到我可以使用sudo来运行Ruby脚本本身,但是不想这样做。

我该怎么做?

1 个答案:

答案 0 :(得分:2)

可以尝试先以当前用户身份创建文件,然后再拥有其所有权和权限,而不是尝试以root用户身份创建或打开文件(如果以非root用户身份启动Ruby脚本,我相信这是不可能的)改变了。

实际上,使用Ruby的Tempfile功能创建初始文件可能很有意义,因为它无需确定唯一的文件名,并且不需要当前目录是可写的。这是我想到的代码(它也发布在https://gist.github.com/keithrbennett/2c6f53351bf9cdb0bbbfd3f7f97dc91c上)。定义了模块,并在最后一行对其进行调用。我做了一些假设,例如该文件应该是世界可读的:

#!/usr/bin/env ruby

require 'tempfile'

module SudoFileWriter

  module_function

  # Writes passed text to a temp file.
  # @return the filespec of the temp file.
  def write_to_temp_file(text)
    filespec = nil
    Tempfile.open do |file|
      file.write(text)
      filespec = file.path
    end
    filespec
  end


  def write_to_root_file(filespec, text)
    temp_filespec = write_to_temp_file(text)
    commands = [
        "sudo chown root:wheel #{temp_filespec}",
        "sudo mv #{temp_filespec} #{filespec}",
        "sudo chmod +r #{filespec}"
    ]
    puts "Running commands for file #{filespec}:\n\n"; puts commands
    `#{commands.join(' && ')}`
  end


  def call(filespec, object_to_write)
    write_to_root_file(filespec, object_to_write.to_s)
  end
end

# .() is shorthand for .call().
# `module_function` above results in all methods being both module level
# and instance level methods, so we can call directly on the module object.

SudoFileWriter.('root-owned-file.txt', "The time is now #{Time.now}.\n")

输出看起来像这样:

Running commands for file root-owned-file.txt:

sudo chown root:wheel /var/folders/bk/8y3jvjs53qs9wlqtpzqq6_080000gn/T/20180810-9981-124bxcl
sudo mv /var/folders/bk/8y3jvjs53qs9wlqtpzqq6_080000gn/T/20180810-9981-124bxcl root-owned-file.txt
sudo chmod +r root-owned-file.txt
Password:
The time is now 2018-08-10 16:01:05 +0700.