hangscer

scala #>等方法: Process and PocessBuilder

2017/10/28

scala #>以及#!等方法: Process and PocessBuilder

1
2
3
4
5
import scala.sys.process._
"ls".! // 返回Int
Process("ls").lineStream // 返回Stream[String]
Seq("ls",dir).!! //返回 String
Seq("find","//Users/jianghang/Coding/scala_maven","-name","*.scala","-type","f").lineStream

ProcessBuilder的方法可以分为三类,

  • 组合两个ProcessBuilder实例,生成第三个ProcessBuilder实例
  • 重定向输入或者输出
  • 执行外部的进程

Combining ProcessBuilder

把两个已经存在的ProcessBuilder组合起来,有以下三种方式:

  • 并行执行,第一个实例的输出作为第二个实例的输入,just like Unix pipes,使用#|方法
  • 按顺序执行,第一部分执行完毕后,第二部分才会执行,没有传递结果的功能,使用###方法
  • 根据第一部分的执行完毕后返回的状态码,决定第二部分是否执行,使用#&&或者#||方法

比如,以下的代码非常像Unix的管道命令:

1
2
3
"ls /" #| "grep App" ! //返回Int
"ls /" #| "grep App" !! //返回String,看到!和!!的区别了吗
"ls /" #> "grep App" !

Redirecting Input/Output

在执行prcess时,可以控制输入和输出,这些方法分别为#<#>#>>。这些方法把其他的ProcessBuilder实例作为输入(类似管道),又或者比如java.io.File或者java.io.InputStream

1
"ls /" #> "grep App" #>> new File("app.txt") !

Starting Process

以下四个方法可以启动process,但是存在区别:

  • run,最通用的方法,它立即返回scala.sys.process.Process实例,与此同时,命令也被异步执行。
  • !,会阻塞执行流直到命令执行完毕退出,并返回状态码。
  • !!,也会阻塞执行流直到命令执行完毕退出,与!,会返回String输出结果。
  • lineStream,立即返回,有点像run,不同的是,返回的是Stream[String],当去去stream中的数据时,有可能阻塞直到值可获得。当执行的命令返回非0状态码,说明命令执行错误,lineStream会抛出异常,需要额外处理。对此,加强版的方法为lineStream_!

example

1
2
3
4
5
6
7
println(("ls /Applications" ### "sleep 5s" ### "ls /Users").run)
println("hello")
//输出
//scala.sys.process.ProcessImpl$ProcessSequence@100fc185 //run 立即返回Process实例
//hello ,异步执行命令
//App Store.app
//Atom.app

当然,你还可以结合curl等等linux常见的工具,实现一句话下载文件等等小功能。