Scala 2.9的"scala.sys.process"如何工作?

Mar*_*tin 59 scala

我刚看了一下new scala.sysscala.sys.processpackage,看看这里有什么有用的东西.但是,我完全失去了.

有没有人举例说明如何实际启动流程?

而且,这对我来说最有趣:你能分离进程吗?

当父进程结束并且是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;
Run Code Online (Sandbox Code Playgroud)

接收指令:

IFF %@Connect[localhost 5554] lt 0 THEN
   ECHO [TCC] Start emulator
   DETACH emulator -avd Nexus-One -no-boot-anim
ENDIFF
Run Code Online (Sandbox Code Playgroud)

在这两种情况下都是火灾和遗忘,模拟器启动并且即使在脚本结束后也将继续运行.当然,必须两次编写脚本是浪费.所以我现在考虑使用Scala进行统一的进程处理,而不使用cygwin或xml语法.

mic*_*ebe 76

首先进口:

import scala.sys.process.Process
Run Code Online (Sandbox Code Playgroud)

然后创建一个ProcessBuilder

val pb = Process("""ipconfig.exe""")
Run Code Online (Sandbox Code Playgroud)

那你有两个选择:

  1. 运行并阻止,直到进程退出

    val exitCode = pb.!
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在后台运行该进程(分离)并获取一个Process实例

    val p = pb.run
    
    Run Code Online (Sandbox Code Playgroud)

    然后你可以从进程中获取exitcode(如果进程仍在运行,则阻塞直到它退出)

    val exitCode = p.exitValue
    
    Run Code Online (Sandbox Code Playgroud)

如果要处理进程的输入和输出,可以使用ProcessIO:

import scala.sys.process.ProcessIO
val pio = new ProcessIO(_ => (),
                        stdout => scala.io.Source.fromInputStream(stdout)
                          .getLines.foreach(println),
                        _ => ())
pb.run(pio)
Run Code Online (Sandbox Code Playgroud)

  • 对于I/O处理,还有一些很好的`#<``#>`便捷方法.坏了,##(s:String)`丢失了 (2认同)

Ale*_*ise 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)
}
Run Code Online (Sandbox Code Playgroud)


Syn*_*sso 8

流程从SBT导入.以下是有关如何使用SBT中显示的流程库的全面指南.

https://github.com/harrah/xsbt/wiki/Process


Dan*_*ral 7

有没有人举例说明如何实际启动流程?

import sys.process._ // Package object with implicits!
"ls"!
Run Code Online (Sandbox Code Playgroud)

而且,这对我来说最有趣:你能分离进程吗?

"/path/to/script.sh".run()
Run Code Online (Sandbox Code Playgroud)

你要做的大部分都与sys.process.ProcessBuilder特质有关.了解这一点.

有一些暗示使得使用不那么冗长,并且它们可以通过包对象获得sys.process.导入其内容,如示例中所示.另外,看看它的scaladoc.


Mar*_*tin 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
}
Run Code Online (Sandbox Code Playgroud)

可悲的是,我无法(没有时间)将其作为中缀操作.因此,建议的召集公约是:

#<<< ("command") {"""
Here Document data
"""}
Run Code Online (Sandbox Code Playgroud)

如果有人能给我一个关于如何让它变得更像shell的暗示,那将是一个电话:

"command" #<<< """
Here Document data
""" !
Run Code Online (Sandbox Code Playgroud)

  • `implicit class HereDocCommand(command:String){def#<<<(hereDoc:String)= ...}` (2认同)