预混合控制台输出来自Ruby的系统调用



我想创建一个Ruby脚本,作为控制台输出的前缀。例如:

我想实现这样一个接口:

puts 'MainLogger: Saying hello'
prefix_output_with('MainLogger') do
  system 'echo hello'
end

所以这显示在控制台中:

MainLogger: Saying hello
MainLogger: hello

在所有系统调用输出前面加上一些记录器是什么好方法?

注意:我不在乎我们是否回显系统调用是什么

这里的重要一点是,无法知道system是否真的会产生输出。我假设您不希望在系统调用没有打印任何内容时使用空白的MainLogger:,因此您需要在shell中使用前缀:

def prefix_system_calls pre
  sys = Kernel.instance_method(:system)
  # redefine to add prefix
  Kernel.send(:define_method, :system) do |cmd|
    sys.bind(self)["#{cmd} | sed -e 's/^/#{pre}: /'"]
  end
  yield
  # redefine to call original method
  Kernel.send(:define_method, :system) do |*args|
    sys.bind(self)[*args]
  end
end
system "echo foo"
prefix_system_calls("prefix") do
  system "echo bar"
end
system "echo baz"
# foo
# prefix: bar
# baz

不过,这个实现非常脆弱。它不能处理调用system的所有不同方式,并且包含特殊shell字符的前缀可能会导致错误。

最新更新