Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 从FileUtils获取执行的命令?_Ruby_Rubygems - Fatal编程技术网

Ruby 从FileUtils获取执行的命令?

Ruby 从FileUtils获取执行的命令?,ruby,rubygems,Ruby,Rubygems,将:verbose标志传递给FileUtils命令时,该命令将打印到STDOUT。有没有一种方法可以捕获命令,以便在其他地方记录或使用它?如果查看FileUtils的源代码,它使用以下方法进行详细输出: def fu_output_message(msg) #:nodoc: @fileutils_output ||= $stderr @fileutils_label ||= '' @fileutils_output.puts @fileutils_label + msg end

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

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

def fu_output_message(msg)   #:nodoc:
  @fileutils_output ||= $stderr
  @fileutils_label  ||= ''
  @fileutils_output.puts @fileutils_label + msg
end
i、 e.它正在将消息写入
@fileutils\u输出
,默认情况下使用
$stderr
。似乎没有改变
@fileutils\u输出的方法,但您可以添加一个:

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 
或者,如果你想把它们串起来,你可以:

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\u output=
方法添加到此模块。)

备选方案

正如在下面的评论中所说,另一种方法是重新分配
$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)
本身。

为了添加到Mike的答案中(因为我无法评论),如果您希望以字符串形式获得输出,我创建了这个包装器
def

def fileutil_out
    out = StringIO.new
    FileUtils.fileutils_output = out
    yield
    return out.string
end

mylog.info fileutil_out { FileUtils.chmod_R(0664, 'file.txt', :verbose => isVerbose) }

我最终没有使用它,因为我想在之后恢复到
@fileutils\u output | |=stderr

这是一个很好的答案。您可以做的另一件事是将$stderr重定向到您自己的对象,这样您就不必打开FileUtils类。当然,您将捕获打印到$stderr的非FileUtils方法的结果。@Joshua Yep,您是对的。实际上,我从重新分配
$stdout
开始采用这种方法,但当这不起作用时(因为它改为写入
$stderr
),我最终深入研究了
文件utils
代码并得出了上述结论。太棒了!非常感谢您给出了明确的答案(以及这里的讨论!),这正是我所需要的:)