This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 12.13, “How to handle the STDOUT and STDERR of external commands.”
You want to run an external command and get access to both its STDOUT and STDERR in a Scala application.
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
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: Int = 1 scala> println(stdout) /usr/bin/make scala> println(stderr) find: /usr/local/mysql-5.0.67-osx10.5-x86/data: Permission denied
Depending on your needs, this can get much more complicated very quickly. The Scaladoc states, “If one desires full control over input and output, then a
ProcessIO can be used with
run.” See the scala.sys.process API documentation for the
ProcessIO classes for more examples.
- The Scala
processpackage object documentation includes many details and examples.