当您将 :verbose 标志传递给 FileUtils 命令时,该命令将打印到 STDOUT。有没有办法捕获命令以便它可以被记录或在其他地方使用?

最佳答案

如果您查看 FileUtils 的源代码,它会使用以下方法进行详细输出:

def fu_output_message(msg)   #:nodoc:
  @fileutils_output ||= $stderr
  @fileutils_label  ||= ''
  @fileutils_output.puts @fileutils_label + msg
end

即它正在将消息写入 @fileutils_output 并且默认情况下它使用 $stderr 。似乎没有改变 @fileutils_output 的方法,但您可以添加一个:
module FileUtils
  def FileUtils.fileutils_output=(new_out)
    @fileutils_output = new_out
  end
end

然后,如果您想将命令捕获到文件中,您可以执行以下操作:
my_fu_log = open('fu_log.log', 'w')
FileUtils.fileutils_output = my_fu_log
# FileUtils operations with :verbose => true here
my_fu_log.close
FileUtils.fileutils_output = $stderr # restore writing to stderr if you want

或者如果你想把它们放在一个字符串中,你可以这样做:
log = StringIO.new
FileUtils.fileutils_output = log
# FileUtils operations with :verbose => true here
# commands are in log.string

此外,还有一个 FileUtils::Verbose 模块,它基本上包含 FileUtils(因此具有所有相同的方法)但默认选项为 :verbose => true,因此如果您想捕获大量命令,您可以使用它而不是每次都指定选项。 (您需要以与上述相同的方式将 fileutils_output= 方法添加到此模块。)

替代品

正如 Joshua 在下面的评论中所说,另一种方法是重新分配 $stderr ,但正如他所说,这确实意味着写入 stderr (不仅仅是 FileUtils )的所有内容都被重定向。如果所有 FileUtils 操作一次发生,中间没有任何其他操作,那么这可能不是问题。所以类似的东西:
orig_stderr = $stderr # keep reference to original stderr
$stderr = my_fu_log
# use FileUtils here
$stderr = orig_stderr # restore stderr

最后,如果您需要更多控制,您可以重新打开 FileUtils 并覆盖 fu_output_message(msg) 本身。

关于ruby - 从 FileUtils 获取执行的命令?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3163585/

10-12 07:21