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

jrd*_*oko 5 ruby redirect stdout ruby-on-rails stderr

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

mu *_*ort 2

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

  • $stdoutSTDOUT
  • $stderrSTDERR

足够聪明的人还可以使用IO.new文件描述符参数打开自己的副本:

sneaky = IO.new(2, 'w')
Run Code Online (Sandbox Code Playgroud)

现在您可以对标准错误流进行可写访问,sneaky而无需与$stderror发生任何关系STDERR

重新分配$stderr$stdout应该可以正常工作,除非您的代码、gems 或 Ruby 本身中的某些内容正在使用常量 ( STDOUT, STDERR) 或直接通过 C 的 stdio、unix 的低级read/write使用数字文件描述符访问流,或者正在打开自己对流使用IO.new. 我还没有深入研究源代码,但我怀疑分配 to$stdout会对stdoutC 领域或 Unix 领域的文件描述符 1 产生任何影响。

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


更新:如果您主要(仅?)关心Rails 应用程序其余部分的更改$stdout$stderr内部script/runner渗透,那么您不必担心这一点。每个进程(您的script/runner进程以及主应用程序运行的许多服务器进程)都有自己的一组全局变量,因此您可以在脚本中更改它们,而不会弄乱您的主应用程序。当然,你仍然需要担心宝石使用STDOUT代替$stderr或使用IO.new来获得自己的私有标准。

  • @jrdioko:“script/runner”将使用自己的进程(控制台也将如此),因此它将有自己的全局变量。 (2认同)