有没有办法在 Crystal 中重定向 STDERR?
Is there a way to redirect STDERR in Crystal?
在测试期间重定向 STDERR
会很方便。这在 Crystal 中可行吗?
仅使用标准库无法做到这一点,但有一个外部库可以执行 low-level 操作。
https://github.com/mosop/stdio
用于捕获标准 I/O 流
的小型 Crystal 库
这是一种可能的方法(灵感来自 https://github.com/mosop/stdio)
dup2
包含在 Libc
中。 dup
必须定义。然后您可以捕获 STDOUT 或 STDERR:
lib LibC
fun dup(oldfd : LibC::Int) : LibC::Int
end
def capture(origin)
close_on_exec = origin.close_on_exec?
begin
o, i = IO.pipe
dup = LibC.dup(origin.fd)
origin.reopen(i)
yield o
LibC.dup2(dup, origin.fd)
origin.close_on_exec = close_on_exec
ensure
o.close if o
i.flush if i
i.close if i
end
end
STDERR.puts "a"
capture(STDERR) { |output|
STDERR.puts "b\nc"
puts output.gets.inspect
puts output.gets.inspect
}
STDERR.puts "d"
capture(STDOUT) { |output| STDOUT.puts "this is ignored" }
puts "done"
在测试期间重定向 STDERR
会很方便。这在 Crystal 中可行吗?
仅使用标准库无法做到这一点,但有一个外部库可以执行 low-level 操作。
https://github.com/mosop/stdio
用于捕获标准 I/O 流
这是一种可能的方法(灵感来自 https://github.com/mosop/stdio)
dup2
包含在 Libc
中。 dup
必须定义。然后您可以捕获 STDOUT 或 STDERR:
lib LibC
fun dup(oldfd : LibC::Int) : LibC::Int
end
def capture(origin)
close_on_exec = origin.close_on_exec?
begin
o, i = IO.pipe
dup = LibC.dup(origin.fd)
origin.reopen(i)
yield o
LibC.dup2(dup, origin.fd)
origin.close_on_exec = close_on_exec
ensure
o.close if o
i.flush if i
i.close if i
end
end
STDERR.puts "a"
capture(STDERR) { |output|
STDERR.puts "b\nc"
puts output.gets.inspect
puts output.gets.inspect
}
STDERR.puts "d"
capture(STDOUT) { |output| STDOUT.puts "this is ignored" }
puts "done"