mol*_*olf 63
在Ruby中,$stderr指的是输出流目前使用的作为标准错误,而STDERR是默认 stderr的流.可以很容易地临时分配不同的输出流$stderr.
require "stringio"
def capture_stderr
# The output stream must be an IO-like object. In this case we capture it in
# an in-memory IO object so we can return the string value. You can assign any
# IO object here.
previous_stderr, $stderr = $stderr, StringIO.new
yield
$stderr.string
ensure
# Restore the previous value of stderr (typically equal to STDERR).
$stderr = previous_stderr
end
Run Code Online (Sandbox Code Playgroud)
现在您可以执行以下操作:
captured_output = capture_stderr do
# Does not output anything directly.
$stderr.puts "test"
end
captured_output
#=> "test\n"
Run Code Online (Sandbox Code Playgroud)
同样的原则也适用于$stdout和STDOUT.
use*_*029 17
这是一个更抽象的解决方案(归功于David Heinemeier Hansson):
def silence_streams(*streams)
on_hold = streams.collect { |stream| stream.dup }
streams.each do |stream|
stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
stream.sync = true
end
yield
ensure
streams.each_with_index do |stream, i|
stream.reopen(on_hold[i])
end
end
Run Code Online (Sandbox Code Playgroud)
用法:
silence_streams(STDERR) { do_something }
Run Code Online (Sandbox Code Playgroud)
gun*_*unn 10
基本上与@ molf的答案相同,具有相同的用法:
require "stringio"
def capture_stderr
real_stderr, $stderr = $stderr, StringIO.new
yield
$stderr.string
ensure
$stderr = real_stderr
end
Run Code Online (Sandbox Code Playgroud)
它更简洁地使用StringIO,并且在调用capture_stderr之前保留$ stderr.
我喜欢StringIO的答案.但是,如果您正在调用外部进程并且$stderr = StringIO.new不起作用,则可以将stderr写入临时文件:
require 'tempfile'
def capture_stderr
backup_stderr = STDERR.dup
begin
Tempfile.open("captured_stderr") do |f|
STDERR.reopen(f)
yield
f.rewind
f.read
end
ensure
STDERR.reopen backup_stderr
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15986 次 |
| 最近记录: |