tags:

views:

1879

answers:

3

IO.popen() and system() in Ruby is sorely lacking several useful features, such as:

  • obtaining the return value of the function
  • capturing both stdout and stderr (seperately and merged)
  • running without spawning an extra cmd.exe or /bin/sh process

Python has a module "subprocess" which I was thinking about using as inspiration for a similar module in Ruby. Now to the questions:

  • How are Ruby-programmers working around the issues above, for example obtaining the return value when doing a popen() call?
  • Is this something which has already been implemented?
+6  A: 
  • system() exit status can be captured with $?.exitstatus
  • stderr can be captured with something like system 'command 2>&1'
Priit
Cool. I didn't know about $?.exitstatus, thanks!
JesperE
+4  A: 

Take a look at the standard ruby library open3. This will give you access to stdin, stdout and stderr.

There is also an external project called open4, which allows you to get the exit status without using a magic variable name.

Aaron Hinni
Note that for Ruby < 1.9 open3 doesn't give the exit status even *with* a global variable name - http://redmine.ruby-lang.org/issues/show/1287
Jordan Brough
A: 

I've felt the need to do exactly that when testing git_remote_branch. The tool calls out to the shell and I wanted to capture exactly what was displayed during test runs, no matter what git was displaying, and no matter if it was being spit out in stdout or stderr.

I have a module that's perfectly reusable that can be observed here (MIT license: use at will, just don't sue me ;-)

You can see it in action in the tests for git_remote_branch here.

Also, I've set up a repo specifically for capture_fu, it includes some tests and stuff. The project's not terribly well set up though. I haven't spent much time making it releasable ;-)

webmat