synapse
synapse

Reputation: 5728

Write to process stdin

How can I get some kind of writeable stream connected to stdin (and also readable streams connected to stdout and stderr) when launching a process via scala.sys.process library? Here's the code that doesn't work (doesn't even print debug messages)

  val p = Process("wc -l")
  val io = BasicIO.standard(true)

  val lines = Seq("a", "b", "c") mkString "\n"
  val buf = lines.getBytes(StandardCharsets.UTF_8)

  io withInput { w =>
    println("Writing")
    w.write(buf)
  }

  io withOutput { i =>
    val s = new BufferedReader(new InputStreamReader(i)).readLine()
    println(s"Output is $s")
  }

Upvotes: 4

Views: 472

Answers (1)

You have a couple of problems.

First in your snippet you never connect your process with the io and never run it. That can be done like this: p run io.

Second, the withInput & withOutput methods return a NEW ProcessIO they DON'T mutate the actual, and since you don't assign the return of those calls to a variable, you are doing nothing.

The following snippet fixes both problems, hope it works for you.

import scala.io.Source
import scala.sys.process._
import java.nio.charset.StandardCharsets

val p = Process("wc -l")
val io =
  BasicIO.standard(true)
    .withInput { w =>
      val lines = Seq("a", "b", "c").mkString("", "\n", "\n")
      val buf = lines.getBytes(StandardCharsets.UTF_8)
      println("Writing")
      w.write(buf)
      w.close()
    }
    .withOutput { i =>
      val s = Source.fromInputStream(i)
      println(s"Output is ${s.getLines.mkString(",")}")
      i.close()
    }

p run io

Don't doubt to ask for clarification.

PS: it prints "Output is 3" - (Thanks to Dima for pointing the mistake).

Upvotes: 2

Related Questions