我有以下测试Ruby脚本:
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
我收到的电子邮件包含以下内容:
test stderr
为什么stderr正确重定向但不是stdout?
修改:为了回复评论,我在$stdout.flush
行后添加了puts
并正确打印。所以我将重申我的问题:发生了什么以及为什么刷新修复它?
答案 0 :(得分:4)
标准输出通常是缓冲的,以避免每次写入时发生系统调用。所以,当你这样说时:
puts 'test stdout'
你实际上只是将该字符串填充到缓冲区中。然后你这样说:
`mail -s 'test' my@email.com < #{tempfile.path}`
并且您的'test stdout'
字符串仍在缓冲区中,因此当tempfile
向您发送文件内容时,它不在mail
中。刷新$stdout
会强制将缓冲区中的所有内容写入磁盘;来自fine manual:
将ios中的任何缓冲数据刷新到底层操作系统(请注意,这只是Ruby内部缓冲;操作系统也可以缓冲数据)。
$stdout.print "no newline" $stdout.flush
产生
no newline
标准错误通常是无缓冲的,因此错误消息(应该是罕见的)立即可见。