System command errors not going to $stderr

I have a Rails project, that uses Windows shares to access printers, and
as part of that will run a command line “net use” to set them up or to
test them. At its simplist:

net use

I wanted to grab any error text to display on the web page, and so have
this method to do just that:

The standard method for calling an OS command gets the stdout

output,

but not the stderr output. This captures the later. Usage:

captured_output = capture_stderr do

result = #{command}

end

“>#{command}\n#{result}\n#{captured_output}\n”

From

Unit tested

def capture_stderr
# The output stream must be an IO-like object.
# In this case we capture it in
# an in-memory IO object so we can return the string value.
# You can assign any
# IO object here.
previous_stderr, $stderr = $stderr, StringIO.new
yield
$stderr.string
ensure
# Restore the previous value of stderr (typically equal to STDERR).
$stderr = previous_stderr
end

I then have two test methods, the first for no error condition, the
second generates an error, which then gets captured. Recently I upgraded
from Java 6 to Java 7 (I had been forced to stick with Java 6 because of
other software), and now the second unit test fails. Having played
around a bit, I have stripped it all down to this:

require ‘stringio’
$stderr = StringIO.new
$stderr.write “No errors so far…”

p ‘-------------------------------------------’
p ‘Good command, no error expected’
result = net use
p “result=#{result}”
p “error=#{$stderr.string}”

p ‘-------------------------------------------’
p ‘Bad command, should see error’
result = net use nonsense_command
p “result=#{result}”
p “error=#{$stderr.string}”

So stderr is redirected to the StringIO object, and I just check I can
write to it. The first time the command completes successful, and result
is set to some long string, and error is just “No errors so far…”.
Great. The second time the command fails, so result is empty… but what
happens to the error text generated? It does not go to $stderr.

I have to admit I have not tried this simple program with Java 6, but my
project did pass all its tests on Friday, and the only change is to
upgrade Java from version 6 to 7.

I am using JRuby 1.7.2 (Ruby 1.9.3, jdk1.7.0_21) on Windows 7 Pro by the
way.

Further investigation reveals this is not just JRuby, but Ruby MRI also,
leaving me mystified as to how it worked previously. Could this be a
Windows problem, and something changed in Windows to stop it working?
Hard to imagine Microsoft bothering to update something like that, but
who knows?

As a work around, I have just appended " 2>&1" to my commands, so error
output is directed to STDOUT at the OS level, all of which is returned
as a string in Ruby.