在Ruby脚本中重定向stdout的问题

问题描述 投票:2回答:1

我有以下测试Ruby脚本:

require 'tempfile'

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

puts 'test stdout'
warn 'test stderr'
`mail -s 'test' [email protected] < #{tempfile.path}`

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

我收到的电子邮件包含以下内容:

test stderr

为什么stderr正确重定向但不是stdout?

编辑:回应评论我在$stdout.flush线后添加了一个puts并正确打印。所以我将重申我的问题:发生了什么以及为什么刷新修复它?

ruby stdout stderr buffering output-redirect
1个回答
4
投票

标准输出通常是缓冲的,以避免每次写入时的系统调用。所以,当你这样说时:

puts 'test stdout'

你实际上只是将该字符串填充到缓冲区中。然后你这样说:

`mail -s 'test' [email protected] < #{tempfile.path}`

并且你的'test stdout'字符串仍然在缓冲区中,所以当tempfile将文件的内容发送给你时它不在mail中。刷新$stdout强制将缓冲区中的所有内容写入磁盘;来自fine manual

将ios中的任何缓冲数据刷新到底层操作系统(请注意,这只是Ruby内部缓冲;操作系统也可以缓冲数据)。

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

生产:

no newline

标准错误通常是无缓冲的,因此错误消息(应该是罕见的)立即可见。

© www.soinside.com 2019 - 2024. All rights reserved.