24

I seem to be stuck trying to retrieve the exit status of a shell command which was started from ruby's Open3.popen3()-method.

Here's my code:

require 'open3'
stdin, stdout, stderr = Open3.popen3('ls')

When I now try to access $? it still is nil

Is it possible to retrieve the exit status after all?

Notes:
- ls is not the command I'm trying to use in my script. I just used this to give an example. My script is a bit more complex and contains user input, which is why I need the sanitizing functionality of Open3.
- I've also tried the block variant of popen3, but didn't succeed with that either.

Gerrit-K
  • 1,298
  • 2
  • 15
  • 30

3 Answers3

34

The concise answer is to use the 4th parameter of open3: wait_thr

  • get whether any error is indicated: wait_thr.value.success?
  • get the actual error level: wait_thr.value.exitstatus

Sample:

Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
  return_value = wait_thr.value
end
puts "Error level was: #{return_value.exitstatus}" unless return_value.success?
Joe Pinsonault
  • 537
  • 7
  • 16
Samuel Bourque
  • 441
  • 4
  • 3
28

popen3 yields/returns four parameters, stdin, stdout, stderr and wait_thr. wait_thr contains a method wait_thr.value which returns the exit status of the command (in fact, it is a Process::Status object according to documentation). Also have a look at http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/Open3.html#method-c-popen3

ckruse
  • 9,642
  • 1
  • 25
  • 25
  • 4
    I knew that open3 also returns a thread but didn't know how to get its exit code. `wait_thr.value.success?` works like a charm, thank you very much! – Gerrit-K Feb 23 '13 at 10:46
2

Everything you need (standard output, error and exit code) in three lines:

require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5; ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"
Pascal
  • 8,464
  • 1
  • 20
  • 31
laimison
  • 1,409
  • 3
  • 17
  • 39