12.12. Handling STDOUT and STDERR for External Commands

Problem

You want to run an external command and get access to both its STDOUT and STDERR.

Solution

The simplest way to do this is to run your commands as shown in previous recipes, and then capture the output with a ProcessLogger. This Scala shell script demonstrates the approach:

#!/bin/sh
exec scala "$0" "$@"
!#

import sys.process._

val stdout = new StringBuilder
val stderr = new StringBuilder

val status = "ls -al FRED" ! ProcessLogger(stdout append _, stderr append _)
println(status)
println("stdout: " + stdout)
println("stderr: " + stderr)

When this script is run, the status variable contains the exit status of the command. The stdout variable contains the STDOUT if the command is successful (such as with ls -al), and stderr contains the STDERR from the command if there are problems. If the command you’re running writes to both STDOUT and STDERR, both stdout and stderr will contain data.

For instance, assuming you don’t run the following command as root, changing the status expression in the script to the following code should generate output to both STDOUT and STDERR on a Unix system:

val status = Seq("find", "/usr", "-name", "make") ! ProcessLogger(stdout append _, stderr append _)

Running the script with this command on a Mac OS X (Unix) system, I correctly get the following exit status, STDOUT, and STDERR output:

scala> val status = Seq("find", "/usr", "-name", "make") ! ProcessLogger(stdout append _, stderr append _) status: ...

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.