1. Computing

Capturing the Return Value of an External Program


Ruby makes it easy to run external programs and capture their output. Using the built-in "backtick" operator is as easy as running these programs from the command line. However, it's not obvious how to capture the return value of these programs.

One way to capture the return value of external programs is to use the $? special variable. I know, special single-character global variables is a bit Perl-like, but it's a simple way to capture the return value. Simply read the value of $? after running the external program.

In this example, we're going to use the ping program. Ping will send ICMP echo requests to a remote host and measure the round trip time. The ping program will return 0 if responses are received from the remote host, and non-zero if no response is received.

 #!/usr/bin/env ruby
 `ping #{ARGV[0]}`
 if $? == 0
   puts "Ping was successful"
   puts "Ping was not successful"

The $? variable is of the type Process::Status. There are a few methods for querying the status of running processes, but these aren't very useful when querying the return value of an external program. What Process::Status does is encapsulate a 16-bit return value on POSIX systems (other systems may have different return value sizes and conventions). Here are some of the most useful methods in Process::Status.

  • success?

    The success? method returns true if the return value of the external program represents a success condition. This usually means it returns true if the return value is 0, however Ruby may take platform-specific conventions into account.

    If you were to re-write the above example to use success?, the line reading if $? == 0 could be replaced with if $?.success?.

  • The & operator

    The & (or bitwise AND) operator allows you to query the return value for specific bits. This is decidedly un-Ruby, but it's the only way to access the high- and low-order bytes of the 16-bit POSIX return value. For example, I was only interested in the low-order byte of the return value, I could use something like $? & 0xff.

  • to_i and to_s

    The to_i and to_s methods expose the 16-bit integer underneath. These are provided both for convenience and compatability. You can use the Process::Status method just like a string or integer because of these methods. Also, Ruby versions before 1.8 simply held the integer return value of an external program in $?, without wrapping it in an object. Because of these methods, older programs that used $? will still work in newer versions of Ruby.

  1. About.com
  2. Computing
  3. Ruby
  4. Beginning Ruby
  5. Capturing the Return Value of an External Program

©2014 About.com. All rights reserved.