Scala 2.9的“scala.sys.process”是如何工作的?
我只是看看新的scala.sys
和scala.sys.process
包,看看这里是否有帮助。 但是,我完全失去了。
有没有人有如何真正开始一个过程的例子?
而且,这对我来说最有趣:你可以分离进程吗?
当父进程结束时,分离的进程将继续运行,并且是Ant的弱点之一。
更新:
似乎有一些混乱是什么分离。 从我目前的项目中获得一个真实的实例。 一次使用z-Shell,一次使用TakeCommand:
Z-shell:
if ! ztcp localhost 5554; then echo "[ZSH] Start emulator" emulator \ -avd Nexus-One \ -no-boot-anim \ 1>~/Library/Logs/${PROJECT_NAME}-${0:t:r}.out \ 2>~/Library/Logs/${PROJECT_NAME}-${0:t:r}.err & disown else ztcp -c "${REPLY}" fi;
接收指令:
IFF %@Connect[localhost 5554] lt 0 THEN ECHO [TCC] Start emulator DETACH emulator -avd Nexus-One -no-boot-anim ENDIFF
在这两种情况下,它是火,忘了,模拟器启动,并将继续运行,即使脚本已经结束。 当然不得不两次写脚本是一件浪费。 所以我现在看着Scala进行统一的stream程处理,没有cygwin或xml语法。
首先import:
import scala.sys.process.Process
然后创build一个ProcessBuilder
val pb = Process("""ipconfig.exe""")
那么你有两个select:
-
运行并阻塞,直到进程退出
val exitCode = pb.!
-
在后台运行进程(分离)并获得一个
Process
实例val p = pb.run
然后你可以从进程中得到exitcode(如果进程仍在运行,它会阻塞直到它退出)
val exitCode = p.exitValue
如果你想处理input和输出的过程,你可以使用ProcessIO
:
import scala.sys.process.ProcessIO val pio = new ProcessIO(_ => (), stdout => scala.io.Source.fromInputStream(stdout) .getLines.foreach(println), _ => ()) pb.run(pio)
我很确定分离的进程工作得很好,考虑到你必须明确地等待它退出,你需要使用线程来照顾stdout和stderr。 这是非常基本的,但这是我一直在使用:
/** Run a command, collecting the stdout, stderr and exit status */ def run(in: String): (List[String], List[String], Int) = { val qb = Process(in) var out = List[String]() var err = List[String]() val exit = qb ! ProcessLogger((s) => out ::= s, (s) => err ::= s) (out.reverse, err.reverse, exit) }
工艺是从SBTimport的。 以下是关于如何使用SBT中显示的过程库的详细指南。
有没有人有如何真正开始一个过程的例子?
import sys.process._ // Package object with implicits! "ls"!
而且,这对我来说最有趣:你可以分离进程吗?
"/path/to/script.sh".run()
你要做的大部分事情都是和sys.process.ProcessBuilder
相关的。 了解这一点。
有一些sys.process
使得使用更sys.process
,并且它们可以通过包对象sys.process
。 导入其内容,如示例中所示。 另外,看看它的scaladoc。
如果有以下文件,以下function将允许使用:
def #<<< (command: String) (hereDoc: String) = { val process = Process (command) val io = new ProcessIO ( in => {in.write (hereDoc getBytes "UTF-8"); in.close}, out => {scala.io.Source.fromInputStream(out).getLines.foreach(println)}, err => {scala.io.Source.fromInputStream(err).getLines.foreach(println)}) process run io }
可悲的是,我没能(没有时间)把它作为中缀操作。 build议的呼叫约定是:
#<<< ("command") {""" Here Document data """}
如果有人能够给我一个关于如何使它像一个更像呼叫的shell的提示,
"command" #<<< """ Here Document data """ !
logging过程稍好一些,大概是两个月的时间。 你可以从我从来没有得到的事实推断我的名单。 不像大多数事情我不这样做,这是我说我会做的事情,所以我很遗憾,它仍然是无证的,因为它到达时。 剑,准备好自己! 我落在你身上!
如果我理解了这个对话框,那么原始问题的一个方面还没有得到答案:
- 如何“分离”产生的进程,以便继续独立于父Scala脚本运行
主要的困难是参与产生进程的所有类必须在JVM上运行,并且当JVM退出时它们不可避免地被终止。 但是,一个解决方法是通过利用shell来代表您“脱离”来间接实现目标。 下面这个启动gvim编辑器的scala脚本看起来可以正常工作:
val cmd = List( “斯卡拉” “-e” “”“import scala.sys.process._;”gvim“.run; System.exit(0);”“” ) val proc = cmd.run
它假定scala在PATH中,并且(不可避免地)保留了JVM父进程的运行。