【问题标题】:How to silence printf called from within a Ruby C extension?如何使从 Ruby C 扩展中调用的 printf 静音?
【发布时间】:2012-01-26 23:24:23
【问题描述】:
  • 我正在运行一个依赖于 C 扩展(而不是对系统的调用)的 Ruby gem。
  • C 代码多次调用 printf。
  • 我想使这些调用的输出静音。
  • 更改 Ruby 的 STDOUT (example) 或 STDERR 不会阻止输出文本。

是否可以在不修改 C 代码的情况下做到这一点?如果有,怎么做?

【问题讨论】:

  • 我记得过去没能找到办法。
  • 运行你的程序时,哪个命令后缀为“2>/dev/null”和“>/dev/null”可以使有问题的printfs静音?另外,它是哪个扩展名?
  • 如果在运行ruby 时重定向stdoutstderr 还不够,那么gem 中肯定有一些特别的事情发生。我们必须看到消息来源才能知道。他们似乎不太可能直接打开/dev/tty 来绕过stdout/stderr,但如果他们没有从ruby 继承stdio,这是我唯一能想到的。
  • @WayneConrad,运行 ruby​​ script.rb >/dev/null 会使输出静音,而 >2/dev/null 不会。
  • @BenJackson,有问题的宝石是 lda-ruby,v. 0.3.8。违规行位于 ext/lda-alpha.c 的第 64 行,它的内容为 printf("alpha maximization : %5.5f %5.5f\n", f, df);。 Grepping 'tty' 和 'dev' 的源代码不会产生任何结果。

标签: c ruby printf stdout


【解决方案1】:

最初有人评论我的帖子建议使用IO.reopen。这对我有用。不幸的是,这个人已经删除了他/她的评论,所以我发布了我最后使用的更详细的功能:

def silence_stdout(log = '/dev/null')
  old = $stdout.dup
  $stdout.reopen(File.new(log, 'w'))
  yield
  $stdout = old
end

用法:

silence_stdout { foo }              # Won't be displayed, won't be logged.
silence_stdout('log.txt') { bar }   # Won't be displayed, logged in log.txt.

【讨论】:

  • 注意 /dev/null 在 Windows 上应该改为 NUL。
  • 是否可以保存到字符串而不是文件中?
【解决方案2】:

Ruby 可能打印到 stderr 而不是 stdout,这就是为什么更改 Ruby 的 stdout 不能解决您的问题。
stderrstdout 通常都进入控制台。)

尝试重定向stderr。我记得应该是:myprogram 2> /dev/null

【讨论】:

  • 我没有想到这一点,但不幸的是这也失败了。
【解决方案3】:

如果您可以访问 C 源代码:

#define printf(...)

此宏形式是 C99 可变参数宏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    相关资源
    最近更新 更多