0

How to execute an operating system command that requires user interaction using a Scala process ?

To illustrate this, consider for instance passwd in Unix/Linux OS, as follows,

import sys.process._
import scala.language.postfixOps

and so

scala> "passwd"!

(current) UNIX password: passwd: Authentication token manipulation error
passwd: password unchanged
Changing password for userabc
res0: Int = 10
elm
  • 20,117
  • 14
  • 67
  • 113

2 Answers2

1

You need to use a ProcessIO instance to handle reading and writing to the stdin/out of the process.

def execute(command: String): Int = {
  def reader(input: java.io.InputStream) = {
    //read here
  }

  def writer(output: java.io.OutputStream) = {
    //write here
  }

  val io = new ProcessIO(writer, reader, err=>err.close())
  Process(command).run(io).exitValue;
}

Something tricky, is that you might need to synchronise your code to write to the stream when there's something expecting the input, otherwise the characters that you write might get lost.

Augusto
  • 28,839
  • 5
  • 58
  • 88
1

Use '!<' instead of '!'

"passwd"!<

From the scala.sys.process.ProcessBuilder trait:

/** Starts the process represented by this builder, blocks until it exits, and
  * returns the exit code.  Standard output and error are sent to the console.
  */
def ! : Int

/** Starts the process represented by this builder, blocks until it exits, and
  * returns the exit code.  Standard output and error are sent to the console.
  * The newly started process reads from standard input of the current process.
  */
def !< : Int
roterl
  • 1,883
  • 14
  • 24
  • `!<` creates an instance of a `ProcessLogger`, but the OP wants to interact with the process by sending data to the stdin of the process. – Augusto Oct 04 '14 at 08:03