某些unix命令如tail -f
或启动python web服务器(即cherrypy)将产生无限输出,即阻止它的唯一方法是Ctrl-C
。我正在开发一个执行命令的scala应用程序,我的实现是:
import scala.sys.process._
def exe(command: String): Unit = {
command !
}
但是,当命令生成无限输出流时,应用程序会挂起,直到我终止它或终止命令启动的进程。我也尝试添加&在命令的最后,为了在后台运行它,但我的应用程序仍然挂起。
因此,我正在寻找另一种方法来执行命令而不会挂起我的应用程序。
答案 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。