在 Ruby 脚本中重定向标准输出的问题 [英] Problem redirecting stdout in Ruby script

查看:49
本文介绍了在 Ruby 脚本中重定向标准输出的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下测试 Ruby 脚本:

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?

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

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}`

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

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:

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

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

产生:

no newline

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

The standard error is often unbuffered so that error messages (which are supposed to be rare) are visible immediately.

这篇关于在 Ruby 脚本中重定向标准输出的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆