From: Brian Marick Date: 2001-09-22T20:09:50+09:00 Subject: [ruby-talk:21521] Re: Interaction system() / $stdout ? Hmm. Perhaps the correct answer to "How do I redirect $stdout" is "Don't." It seems that if you redirect $stdout, output to $defout is also redirected. However, before the redirection, mixtures of messages to $stdout and $defout are printed in the order they're executed. After, they're not (NT, ruby 1.6.3). Not surprising, as $stdout and $defout are now different objects (because of having to clone the original value of $stdout.) When redirecting $defout, it seems you don't have to clone it to restore it. So everything can be put back together so that $stdout, $defout, and $> are once again the same object. Moreover, you don't need the hack I mentioned previously, where you can't close the file until after you restore $stdout: $save_for_close = $stdout $stdout = $original_stdout $save_for_close.close You can do it the simple way: $defout.close $defout = $saved_defout When redirecting $defout, output to $stdout isn't redirected. But that might be OK. What uses $stdout? (I was surprised to see that 'p' doesn't use $stdout - it appears to use $defout.) (Perhaps 'ruby -w' should warn about assignments to $stdout?) Code that demonstrates all this below. ========================================= puts "This is an example of redirecting $stdout to log-file." def inspector(tag) puts "=============" puts "#{tag}, $stdout = #{$stdout.inspect}, $defout=#{$defout.inspect}, $> = #{$>.inspect}" end inspector("Originally") $stdout.puts "A message to $stdout - shows ordering preserved." $defout.puts "A message to $defout - shows ordering preserved." $stdout.puts "Another message to $stdout - shows ordering preserved." $defout.puts "Another message to $defout - shows ordering preserved." $saved_original = $stdout.dup $stdout = File.open("log-file", "w") inspector("After redirect") $stdout.puts "After redirect, $stdout goes to log-file." $defout.puts "After redirect, $defout goes to log-file." $>.puts "After redirect, $> goes to log-file." p "Note that 'p' is redirected as well." $save_for_close = $stdout $stdout = $saved_original $save_for_close.close inspector("After restoration") $stdout.puts "After restoration, $stdout goes to standard output." $defout.puts "After restoration, $defout goes to standard output." $>.puts "After restoration, $> goes to standard output." $stdout.puts "Another message to $stdout - shows ordering no longer preserved." $defout.puts "Another message to $defout - shows ordering no longer preserved." ================== puts "This is an example of redirecting $defout to log-file." def inspector(tag) puts "=============" puts "#{tag}, $stdout = #{$stdout.inspect}, $defout=#{$defout.inspect}, $> = #{$>.inspect}" end inspector("Originally") $stdout.puts "A message to $stdout - shows ordering preserved." $defout.puts "A message to $defout - shows ordering preserved." $stdout.puts "Another message to $stdout - shows ordering preserved." $defout.puts "Another message to $defout - shows ordering preserved." $saved_original = $defout $defout = File.open("log-file", "w") inspector("After redirect") $stdout.puts "After redirect, $stdout goes to standard output." $defout.puts "After redirect, $defout goes to log-file." $>.puts "After redirect, $> goes to log-file." p "Note that 'p' is redirected as well." $defout.close $defout = $saved_original inspector("After restoration") $stdout.puts "After restoration, $stdout goes to standard output." $defout.puts "After restoration, $defout goes to standard output." $>.puts "After restoration, $> goes to standard output." $stdout.puts "Another message to $stdout - shows ordering preserved." $defout.puts "Another message to $defout - shows ordering preserved." -- Brian Marick, marick@testing.com www.testing.com - Software testing services and resources www.testingcraft.com - Where software testers exchange techniques www.visibleworkings.com - Adequate understanding of system internals