我刚刚查看了新的scala.sys
和scala.sys.process
软件包,看看这里是否有帮助。但是,我完全失去了。
有没有人举例说明如何实际启动流程?
而且,对我来说最有趣的是:你能分离过程吗?
父进程结束时,分离进程将继续运行,并且是Ant的弱点之一。
更新
分离是什么似乎有些混乱。从我当前的项目中获得真实的实例。一次使用z-Shell,一次使用TakeCommand:
Z-外壳:
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进行统一的进程处理,而不使用cygwin或xml语法。
答案 0 :(得分:76)
首先导入:
import scala.sys.process.Process
然后创建一个ProcessBuilder
val pb = Process("""ipconfig.exe""")
然后你有两个选择:
运行并阻止,直到进程退出
val exitCode = pb.!
在后台运行该进程(已分离)并获取Process
实例
val p = pb.run
然后你可以从进程中获取exitcode(如果进程仍在运行,则阻塞直到它退出)
val exitCode = p.exitValue
如果您想处理流程的输入和输出,可以使用ProcessIO
:
import scala.sys.process.ProcessIO
val pio = new ProcessIO(_ => (),
stdout => scala.io.Source.fromInputStream(stdout)
.getLines.foreach(println),
_ => ())
pb.run(pio)
答案 1 :(得分:24)
我非常确定分离进程工作得很好,考虑到你必须明确等待它退出,你需要使用线程来管理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)
}
答案 2 :(得分:8)
流程从SBT导入。以下是有关如何使用SBT 中显示的流程库的详尽指南。
答案 3 :(得分:7)
有没有人得到如何做的例子 实际上是开始一个过程吗?
import sys.process._ // Package object with implicits!
"ls"!
而且,这对我来说最有趣: 你可以分离流程吗?
"/path/to/script.sh".run()
你要做的大部分工作都与sys.process.ProcessBuilder
有关。了解这一点。
有些含义使得使用更简洁,并且可以通过包对象sys.process
获得。导入其内容,如示例中所示。另外,看看它的scaladoc。
答案 4 :(得分:6)
以下功能将允许在此处使用文档:
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
}
可悲的是,我无法(没时间)将其作为中缀操作。因此,建议的召集惯例是:
#<<< ("command") {"""
Here Document data
"""}
如果有人能给我一个关于如何让它变得更像shell的暗示,那将是一个电话:
"command" #<<< """
Here Document data
""" !
答案 5 :(得分:3)
记录过程好一点,在我的名单上排名第二,大概两个月。你可以从我从未得到它的事实推断我的列表。不像我不做的大多数事情,这是我说过我会做的事情,所以我非常遗憾它仍然没有像它到达时那样无证。剑,准备好了!我落在你身上!
答案 6 :(得分:2)
如果我理解对话框到目前为止,原始问题的一个方面尚未得到解答:
主要的困难是产生进程所涉及的所有类必须在JVM上运行,并且当JVM退出时它们不可避免地被终止。但是,解决方法是通过利用shell代表您进行“分离”来间接实现目标。以下用于启动gvim编辑器的scala脚本似乎可以正常工作:
val cmd = List( "scala", "-e", """import scala.sys.process._ ; "gvim".run ; System.exit(0);""" ) val proc = cmd.run
它假设scala在PATH中,并且(不可避免地)确实会使JVM父进程运行。