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?
The standard output and standard error streams are generally accessible in two ways each:
$stdout
and STDOUT
$stderr
and STDERR
A sufficiently clever person could also open their own copies using IO.new
with a file descriptor argument:
sneaky = IO.new(2, 'w')
And now you have writable access to the standard error stream through sneaky
without having anything to do with $stderr
or STDERR
.
Reassigning $stderr
and $stdout
should 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 level read
/write
with numeric file descriptors or is opening their own access to the streams using IO.new
. I haven't dug into the source but I doubt assigning to $stdout
will do anything to stdout
in 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 $stdout
and $stderr
inside your script/runner
bleeding into the rest of your Rails app then you don't have to worry about that. Each process — your script/runner
process 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 using STDOUT
instead of $stderr
or using IO.new
to get their own private standard out.
I typically run all my cron jobs through a wrapper script which saves stdout/err and prints it all iff the subprocess exits with a non-zero error code (so I get an email from cron on failure).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With