将:verbose
标志传递给FileUtils命令时,该命令将打印到STDOUT。有没有办法捕获命令,以便可以记录或在其他地方使用?
答案 0 :(得分:4)
如果您查看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)
。
答案 1 :(得分:0)
要添加到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_output ||= $stderr
。