【问题标题】:Problem redirecting stdout in Ruby script在 Ruby 脚本中重定向标准输出的问题
【发布时间】:2011-10-05 18:08:30
【问题描述】:

我有以下测试 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 不正确?

编辑:作为对评论的回应,我在puts 行之后添加了$stdout.flush,并且打印正确。所以我要重申我的问题:发生了什么,为什么刷新会修复它?

【问题讨论】:

  • 切换warn和puts的顺序会发生什么?
  • 当我切换warn 和puts 的顺序时没有任何反应。 @mu:我将mail 更改为cat,正如您所写的那样,但我仍然没有打印出标准输出。我在 CentOS Linux 上使用 Ruby Enterprise Edition 2011.01。

标签: ruby stdout stderr buffering output-redirect


【解决方案1】:

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

puts 'test stdout'

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

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

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

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

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

产生:

no newline

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

【讨论】:

  • 关于标准错误缓冲的有趣和好点。我发布了related question 以更好地理解这一切。
猜你喜欢
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 2022-11-10
  • 2016-03-01
相关资源
最近更新 更多