在Rails应用程序中重新定义$ stdout和$ stderr的副作用

时间:2011-07-13 16:16:38

标签: ruby-on-rails ruby redirect stdout stderr

我想暂时将$stdout$stderr重定向到脚本中的文件,该脚本将由Rails应用中的script/runner运行。这样做有潜在的副作用吗?更改全局变量会导致输出流在我的脚本期间在Rails应用程序的其他部分中重定向吗?那么脚本使用的其他库或线程呢?

3 个答案:

答案 0 :(得分:2)

我通常通过wrapper script运行我的所有cron作业,如果子进程以非零错误代码退出(因此我在失败时从cron收到一封电子邮件),则会保存stdout / err并将其全部打印出来。 / p>

答案 1 :(得分:2)

标准输出和标准错误流通常分两种方式访问​​:

  • $stdoutSTDOUT
  • $stderrSTDERR

一个聪明的人也可以使用带有文件描述符参数的IO.new来打开自己的副本:

sneaky = IO.new(2, 'w')

现在,您可以通过sneaky对标准错误流进行可写访问,而无需与$stderrSTDERR进行任何关联。

重新分配$stderr$stdout应该可以正常工作,除非您的代码,宝石或Ruby本身使用常量(STDOUTSTDERR)或正在访问流直接通过C的stdio,unix的低级read / write和数字文件描述符,或者使用IO.new打开他们自己对流的访问。我没有深入挖掘源代码,但我怀疑分配给$stdout会对C-land中的stdout或Unix-land中的文件描述符1做任何事情。

如果你真的需要捕获标准输出和错误流,那么你最好还是编写一个包装器shell脚本来为你重定向流。


更新:如果您(仅限?)担心将$stdout内的$stderrscript/runner更改为您的Rails应用中的其余部分那你就不用担心了。每个进程 - 您的script/runner进程以及主应用程序运行的许多服务器进程都会获得自己的全局变量集,以便您可以在脚本中更改它们,而不会使主应用程序混乱。当然,您仍然需要担心使用STDOUT代替$stderr或使用IO.new获取自己的私有标准的宝石。

答案 2 :(得分:0)

当然,这取决于您使用的其他宝石,您的日志记录和服务器如何配置。我猜,后续问题是,你为什么需要这个?可能有更好的方法来实现目标。