处理执行Unix命令,产生无穷无尽的输出

时间:2014-03-14 14:40:35

标签: scala process

某些unix命令如tail -f或启动python web服务器(即cherrypy)将产生无限输出,即阻止它的唯一方法是Ctrl-C。我正在开发一个执行命令的scala应用程序,我的实现是:

import scala.sys.process._
def exe(command: String): Unit = {
    command !
}

但是,当命令生成无限输出流时,应用程序会挂起,直到我终止它或终止命令启动的进程。我也尝试添加&在命令的最后,为了在后台运行它,但我的应用程序仍然挂起。

因此,我正在寻找另一种方法来执行命令而不会挂起我的应用程序。

3 个答案:

答案 0 :(得分:3)

您可以使用自定义ProcessLogger来处理您想要的输出。

val proc = 
  Process(command).run(ProcessLogger(line => (), err => println("Uh-oh: "+err)))

您可以使用destroy方法终止进程。

proc.destroy

如果您在等待输出之前获得某个输出,则可以创建一个自定义ProcessLogger,一旦满足其需要,就可以在其自己的流程上调用destroy

您可能更喜欢使用lines(在2.10中;名称在2.11中更改为lineStream而不是run来收集标准输出,因为这会为您提供一个流将在没有新输出可用时阻止。然后将整个事物包裹在Future中,从流中读取行,直到获得所需内容,然后终止进程 - 这简化了阻塞/等待。

答案 1 :(得分:2)

Seq("sh", "-c", "tail -f /var/log/syslog > /dev/null &") !

适合我。我认为Randall的答案失败了因为scala只是执行命令,并且不能解释像“&”这样的shell运算符。如果传递给scala的命令是“sh”并且参数是完整的shell命令,我们可以解决此问题。 scala如何解析/分离单个参数似乎也存在问题,使用Seq而不是单个String对此更有效。

以上相当于unix命令:

sh -c 'tail -f /var/log/syslog > /dev/null &'

答案 2 :(得分:0)

如果您关闭了您正在阅读该流程的描述符'输出,它将获得SIGPIPE和(通常)终止。

如果您不想要输出,请重定向到/dev/null

command arg arg arg >/dev/null 2>&1

附录:这仅适用于类似Unix的系统,而不适用于Windows。