开发者

Problem redirecting stdout in Ruby script

开发者 https://www.devze.com 2023-03-20 05:36 出处:网络
I have the following test Ruby script: require \'tempf开发者_开发问答ile\' tempfile = Tempfile.new \'test\'

I have the following test Ruby script:

require 'tempf开发者_开发问答ile'

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?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消