2

I have the following test Ruby script:

require 'tempfile'

tempfile = Tempfile.new 'test'
$stderr.reopen tempfile
$stdout.reopen tempfile

puts 'test stdout'
warn 'test stderr'
`mail -s 'test' my@email.com < #{tempfile.path}`

tempfile.close
tempfile.unlink
$stderr.reopen STDERR
$stdout.reopen STDOUT

The email that I get has the contents:

test stderr

Why is stderr redirecting properly but not stdout?

Edit: In response to a comment I added a $stdout.flush after the puts line and it printed correctly. So I'll restate my question: what was happening and why does the flush fix it?

jrdioko
  • 32,230
  • 28
  • 81
  • 120
  • What happens when you switch the order of warn and puts? – Seamus Abshere Jul 14 '11 at 22:57
  • Nothing happens when I switch the order of `warn` and `puts`. @mu: I changed the `mail` to `cat` exactly as you wrote and I still don't get the stdout printed. I'm using Ruby Enterprise Edition 2011.01 on CentOS Linux. – jrdioko Jul 14 '11 at 23:01

1 Answers1

4

The standard output is generally buffered to avoid a system call for every write. So, when you say this:

puts 'test stdout'

You're actually just stuffing that string into the buffer. Then you say this:

`mail -s 'test' my@email.com < #{tempfile.path}`

and your 'test stdout' string is still in the buffer so it isn't in tempfile when mail sends the file's content to you. Flushing $stdout forces everything in the buffer to be written to disk; from the fine manual:

Flushes any buffered data within ios to the underlying operating system (note that this is Ruby internal buffering only; the OS may buffer the data as well).

$stdout.print "no newline"
$stdout.flush

produces:

no newline

The standard error is often unbuffered so that error messages (which are supposed to be rare) are visible immediately.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • Interesting, and good point about stderr buffering. I posted a [related question](http://stackoverflow.com/questions/6701103/understanding-ruby-and-os-i-o-buffering) to understand all this better. – jrdioko Jul 14 '11 at 23:21