You want to run an external program as in Recipe 20.8, but you also want to capture the standard error stream. Using popen only gives you access to the standard output.
Use the open3 library in the Ruby standard library. Its popen3 method takes a code block, to which it passes three IO streams: one each for standard input, output, and error.
Suppose you perform the Unix ls command to list a nonexistent directory. ls will rightly object to this and write an error message to its standard error stream. If you invoked ls with IO.popen or the %x{} construction, that error message is passed right along to the standard error stream of your Ruby process. You can capture it or suppress it:
%x{ls no_such_directory} # ls: no_such_directory: No such file or directory
But if you use popen3, you can grab that error message and do whatever you want with it:
require open3 Open3.popen3(ls -l no_such_directory) { |stdin, stdout, stderr| stderr.read } # => "ls: no_such_directory: No such file or directory "
The same caveats in the previous recipe apply to the IO streams returned by popen3. If you e running a command that accepts data on standard input, and you read from stdout before closing stdin, your process will hang.
Unlike IO.popen, the popen3 method is only implemented on Unix systems. However, the win32-open3 package (part of the Win32Utils project) provides a popen3 implementation.
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration