def with_captured_stdout
original_stdout = $stdout # capture previous value of $stdout
$stdout = StringIO.new # assign a string buffer to $stdout
yield # perform the body of the user code
$stdout.string # return the contents of the string buffer
ensure
$stdout = original_stdout # restore $stdout to its previous value
end
# Set up standard output as a StringIO object.
foo = StringIO.new
$stdout = foo
# Send some text to $stdout.
puts 'hi'
puts 'bye'
# Access the data written to standard output.
$stdout.string
# => "hi\nbye\n"
# Send your captured output to the original output stream.
STDOUT.puts $stdout.string
# capture_stream(stream) { block } -> String
#
# Captures output on +stream+ for both Ruby code and subprocesses
#
# === Example
#
# capture_stream($stdout) { puts 1; system("echo 2") }
#
# produces
#
# "1\n2\n"
#
def capture_stream(stream)
raise ArgumentError, 'missing block' unless block_given?
orig_stream = stream.dup
IO.pipe do |r, w|
# system call dup2() replaces the file descriptor
stream.reopen(w)
# there must be only one write end of the pipe;
# otherwise the read end does not get an EOF
# by the final `reopen`
w.close
t = Thread.new { r.read }
begin
yield
ensure
stream.reopen orig_stream # restore file descriptor
end
t.value # join and get the result of the thread
end
end
class Captor < Queue
alias_method :write, :push
def method_missing(meth, *args)
false
end
def respond_to_missing?(*args)
true
end
end
stream = Captor.new
orig_stdout = $stdout
$stdout = stream
puts_thread = Thread.new do
loop do
puts Time.now
sleep 0.5
end
end
5.times do
STDOUT.print ">> #{stream.shift}"
end
puts_thread.kill
$stdout = orig_stdout
9条答案
按热度按时间kiz8lqtg1#
将stdout捕获为字符串的方便函数.
下面的方法是一个方便的通用工具,用于捕获标准输出并将其作为字符串返回。(我经常在单元测试中使用这个方法,我想验证打印到标准输出的内容。)特别注意使用
ensure
子句来恢复$标准输出(并避免惊讶):字符串
例如:
型
wb1gzix02#
将标准输出重定向到StringIO对象
你当然可以将标准输出重定向到一个变量。例如:
字符串
在实践中,这可能不是一个好主意,但至少现在你知道这是可能的。
6psbrbz93#
如果您的项目中有activesupport,您可以执行以下操作:
字符串
关于
Kernel.capture
的更多信息可以在here中找到8wigbo564#
你可以通过在反引号内调用你的R脚本来做到这一点,就像这样:
字符串
有关在Ruby中运行子进程的更多信息,请查看this Stack Overflow question。
sulc1iza5#
捕获Ruby代码 * 和 * 子进程的stdout(或stderr)
字符串
我的灵感来自Zhon。
kmbjn2e36#
对于大多数实际用途,您可以将任何响应
write
、flush
、sync
、sync=
和tty?
的内容放入$stdout
中。在这个例子中,我使用了stdlib中修改过的Queue。
字符串
如果你想主动地对数据进行操作,而不是在任务完成后查看数据,你需要这样的东西。使用StringIO或文件将有问题,因为多个线程试图同时同步读取和写入。
mi7gmzs67#
Minitest
版本:assert_output
如果你需要确保是否生成了一些输出:字符串
Assert输出
或者如果你真的需要捕获它,使用
capture_io
:型
捕获IO
Minitest
本身可以在从1.9.3
开始的任何Ruby版本中使用nfg76nw08#
对于RinRuby,请知道R有
capture.output
:字符串
rn0zuynd9#
感谢@girasquid的回答。我将其修改为单个文件版本:
字符串