有没有办法在 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"