When you pass the :verbose flag to a FileUtils command, the command gets printed to stdout - is there a way to capture the command so it can be logged or used elsewhere?
If you look at the source for FileUtils
it uses the following method for doing its verbose output:
def fu_output_message(msg) #:nodoc:
@fileutils_output ||= $stderr
@fileutils_label ||= ''
@fileutils_output.puts @fileutils_label + msg
end
i.e. it is writing the messages to @fileutils_output
and by default it is using $stderr
. There doesn't seem to be a method to alter @fileutils_output
but you could add one:
module FileUtils
def FileUtils.fileutils_output=(new_out)
@fileutils_output = new_out
end
end
Then if you wanted to capture the commands into a file you could do:
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
or if you wanted to get them in a string you could do:
log = StringIO.new
FileUtils.fileutils_output = log
# FileUtils operations with :verbose => true here
# commands are in log.string
Also, there is a module FileUtils::Verbose
which basically includes FileUtils
(so has all the same methods) but defaults the options to :verbose => true
so if you wanted to capture lots of commands you could use this instead of specifying the option each time. (you would need to add the fileutils_output=
method to this module in the same way as above.)
Alternatives
As Joshua says in the comments below, an alternative is to reassign $stderr
but as he says this does mean that everything written to stderr (not just by FileUtils
) is redirected. If all the FileUtils
operations are happening in one go without anything else in between then this might not be an issue. So something along the lines of:
orig_stderr = $stderr # keep reference to original stderr
$stderr = my_fu_log
# use FileUtils here
$stderr = orig_stderr # restore stderr
Finally, you could reopen FileUtils
and override fu_output_message(msg)
itself if you need more control.