Return code from Open3.popen?

Hi,

Is there a (non-hackish) way to get the error code from Open3.popen()?
The only way I seem to be able to do it currently is by appending "echo
$?" to the command, and parsing it out of stdout. $?.exitstatus contains
some random value.

Andres Salomon wrote:

Hi,

Is there a (non-hackish) way to get the error code from

Open3.popen()?

The only way I seem to be able to do it currently is by appending

"echo

$?" to the command, and parsing it out of stdout. $?.exitstatus

contains

some random value.

The normal way of getting an error out of Open3.popen3 is to check the
STDERR handle:

fin, fout, ferr = Open3.popen3("ls")
error = ferr.gets
if error
puts "Error: " + error.to_s # There was an error
end
....

Regards,

Dan

Daniel Berger wrote:

Is there a (non-hackish) way to get the error code from

Open3.popen()?

The only way I seem to be able to do it currently is by appending

"echo

$?" to the command, and parsing it out of stdout. $?.exitstatus

contains

some random value.

The normal way of getting an error out of Open3.popen3 is to check the
STDERR handle:

fin, fout, ferr = Open3.popen3("ls")
error = ferr.gets
if error
puts "Error: " + error.to_s # There was an error
end

I know of at least one programm using stderr for output even when execution
was successfull!

ยทยทยท

--
Martin Kaletsch

Yes, there are certainly plenty out there.

Really, there needs to be a consistent interface for this sort of
thing; there are plenty of functions out there that execute commands
(IO.popen, Kernel.system, Open3.popen3, etc) that all do slightly
different things wrt $?, depending upon their implementation. That
should be hidden from the user; it should also be possible to define
your own method to run commands in ruby, and override $? (it is
currently read-only from within ruby). Personally, I'd rather see an
exception thrown if the command fails, perhaps w/ an additional
argument to specify that you don't care if the command fails. How that
should happen within IO.popen()'s block is interesting, though. As it
stands, $? is not set until the block exits. So:

IO.popen('nonexistantcommand') { |f|
puts $?.exitstatus
}
puts $?.exitstatus

The first will return the last command run *before* the popen. If the
command exits immediately (ie, because the command doesn't exist),
should an exception be thrown as soon as it is realized that the
command failed? Or, should the block be executed regardless of whether
the command failed or not, and an exception thrown after the block as
completed?

I don't see this as an issue with Ruby, but with the programs that
don't indicate success vs failure properly. There is simply no
consistent way to determine failure with such programs that I know of.

You will have to create special wrappers for whatever it is you're
trying to execute. I had to do this with one of my own packages, where
warnings were sent to STDERR, though the program attempt didn't
actually fail. I literally had to parse warning messages and handle
that separately.

Dan