Problem redirecting stdout in Ruby script

感情迁移 提交于 2019-12-07 18:32:32

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/6700726/problem-redirecting-stdout-in-ruby-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!