In Python, if I want to call an external command as a subprocess, I do the following:
from subprocess import Popen, PIPE
cmd = ['cat', '-be']
out, err = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate("some input")
What's the standard way to do the same in Scala? Using Java's ProcessBuilder I came up with the following, but it's pretty ugly:
def communicate(cmd: List[String], input: Option[String] = None): (String, String) = {
val command = new java.util.ArrayList[String]()
cmd.foreach(command.add(_))
val builder = new ProcessBuilder(command)
val process = builder.start()
val stdinWriter = new java.io.PrintWriter((new java.io.OutputStreamWriter(new java.io.BufferedOutputStream(process.getOutputStream()))), true);
val stdoutReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()))
val stderrReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getErrorStream()))
input.foreach(stdinWriter.write(_))
stdinWriter.close()
def read(reader: java.io.BufferedReader): String = {
val out = new ListBuffer[String]
var line: String = reader.readLine()
while (line != null) {
out += line
line = reader.readLine()
}
return out.result.mkString("\n")
}
val stdout = read(stdoutReader)
val stderr = read(stderrReader)
stdoutReader.close()
stderrReader.close()
return (stdout, stderr)
}
val (catout, caterr) = communicate(List("cat", "-be"), Some("some input"))
val (pwdout, pwderr) = communicate(List("pwd"))
Is there a better alternative built into Scala already?
The answer here How does the “scala.sys.process” from Scala 2.9 work? shows how to use the new Scala 2.9 scala.sys.process.Process. If you don't use 2.9 you can use the process part of sbt; which the Scala process originates from.
Using the OS-Lib library, your code can be written as the following Scala:
@ val res = os.proc("cat", "-be").call(stdin = "some input")
res: os.CommandResult = CommandResult(0, List(Left( 1 some input)))
@ res.out.string
res3: String = " 1\tsome input"
@ res.err.string
res4: String = ""
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With