From: Brian Candler Date: 2013-01-03T22:37:45+09:00 Subject: Re: temporarily override a methode However, what you have written doesn't handle your desired case of redirecting system("ls"). This is because commands run by system() inherit the ruby process's stdout/stderr file descriptors, and write directly to them (not touching any Ruby objects) Here's a possible solution, setting stdout and stderr to point to new pipes which the ruby process consumes in the background. class Tee def self.tee(logfile, append=true) file = File.open(logfile, append ? 'a' : 'w') stdout_old = $stdout.dup stderr_old = $stderr.dup #stdout_old.close_on_exec = true # only in ruby 1.9 #stderr_old.close_on_exec = true # only in ruby 1.9 stdout_r, stdout_w = IO.pipe stderr_r, stderr_w = IO.pipe t1 = Thread.new do while data = stdout_r.readpartial(1024) rescue nil stdout_old.write(data) file.write(data) end stdout_r.close end t2 = Thread.new do while data = stderr_r.readpartial(1024) rescue nil stderr_old.write(data) file.write(data) end stderr_r.close end begin $stdout.reopen(stdout_w) $stderr.reopen(stderr_w) yield ensure $stdout.reopen(stdout_old) $stderr.reopen(stderr_old) [stdout_w,stderr_w].each { |f| f.close } t1.join t2.join [stdout_old,stderr_old,file].each { |f| f.close } end end end puts "start" Tee::tee("logfile.log", true) { puts "Hello" printf "Hello again" system("ls -l") } puts "end" -- Posted via http://www.ruby-forum.com/.