在 Ruby 脚本中重定向标准输出的问题 [英] Problem redirecting stdout in Ruby script
问题描述
我有以下测试 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屋!