I’d like to temporarily redirect $stdout and $stderr to a file in a script that will be run by script/runner in a Rails app. Are there any potential side effects to doing so? Will changing the global variable cause the output streams to be redirected in other parts of the Rails application during the duration of my script? What about other libraries or threads used by the script?
I’d like to temporarily redirect $stdout and $stderr to a file in a script
Share
The standard output and standard error streams are generally accessible in two ways each:
$stdoutandSTDOUT$stderrandSTDERRA sufficiently clever person could also open their own copies using
IO.newwith a file descriptor argument:And now you have writable access to the standard error stream through
sneakywithout having anything to do with$stderrorSTDERR.Reassigning
$stderrand$stdoutshould work fine unless something in your code, your gems, or Ruby itself is using the constants (STDOUT,STDERR) or is accessing the streams directly through C’s stdio, unix’s low levelread/writewith numeric file descriptors or is opening their own access to the streams usingIO.new. I haven’t dug into the source but I doubt assigning to$stdoutwill do anything tostdoutin C-land or file descriptor 1 in Unix-land.If you really need to trap the standard output and error streams then you’re probably better off writing a wrapper shell script to redirect the streams for you.
UPDATE: If you’re mostly (only?) concerned about changing
$stdoutand$stderrinside yourscript/runnerbleeding into the rest of your Rails app then you don’t have to worry about that. Each process — yourscript/runnerprocess and however many server processes your main application has running — gets its own set of globals so you can change them all you want in your script without making a mess of your main application. Of course, you still have to worry about gems usingSTDOUTinstead of$stderror usingIO.newto get their own private standard out.