与Scala中生成的进程交互

时间:2014-08-20 18:10:37

标签: scala process

我可以使用Python来控制gnuplot以交互方式打印出情节,如下所示:

p = Popen(["/usr/local/bin/gnuplot"], shell=False, stdin=PIPE, stdout=PIPE)
p.stdin.write(r'set terminal gif;')
...
out, err = p.communicate()

如何使用Scala做同样的事情?我有一些骷髅代码,但我不确定如何填补缺失的空白。

val gnuplot = "/usr/local/bin/gnuplot"
val pb = Process(gnuplot)
val pio = new ProcessIO(_ => (),
                        stdout => ...,
                        _ => ())
pb.run(pio)

2 个答案:

答案 0 :(得分:2)

此代码工作正常,使用流获取inputStream和编写gnuplot命令:

  def plot(): Unit = {
    val inputStream = new SyncVar[OutputStream];
    val gnuplot = "/usr/local/bin/gnuplot"
    val pb = Process(gnuplot)
    val pio = new ProcessIO(stdin => inputStream.put(stdin),
      stdout => Source.fromInputStream(stdout).getLines.foreach(println),
      stderr => Source.fromInputStream(stderr).getLines.foreach(println));

    pb.run(pio)
    val a = Array("set terminal gif", "set output \"hello.gif\"", "plot [-3.14:3.14] sin(x)").foreach { s =>
      inputStream.get.write((s + "\n").getBytes)
    }
    inputStream.get.close()
  }

答案 1 :(得分:1)

重新调整你的榜样是非常重要的:

 def plot2(): Unit = {
    val done = new CountDownLatch(1)
    val cmds = List(
      "set terminal gif",
      """set output "hello2.gif"""",
      "plot [-3.14:3.14] sin(x)",
      "exit"
    )
    val gnuplot = "/usr/bin/gnuplot"
    val pb = Process(gnuplot)
    val pio = BasicIO standard { out =>
      for (c <- cmds) {
          Console println s">$c"
          out.write(s"$c\n".getBytes)
      }
      try out.close()
      finally done.countDown()
    }
    val p = pb run pio
    if (done.await(10, Seconds)) Console println s"Exited ${p.exitValue}"
    else {
      Console println "Stuck..."
      p.destroy()
    }
  }

我不知道为什么这个API感觉如此复杂。

他们似乎希望在Java 8中添加p.waitFor超时。