用法 一
trait ProcessBuilder extends Source with Sink
表示可以执行的一个或多个外部进程的序列。ProcessBuilder
可以是单个外部进程,也可以是其他 ProcessBuilder
的组合。人们可以控制外部流程的输出将去往何处,其输入将来自何处,或者将决定权留给启动它的人。
通过scala.sys.process.Process 的伴随对象中提供的工厂或基于包对象scala.sys.process 中提供的这些工厂的隐式转换来创建ProcessBuilder
。这里有些例子:
import scala.sys.process._
// Executes "ls" and sends output to stdout
"ls".!
// Execute "ls" and assign a `LazyList[String]` of its output to "contents".
val contents = Process("ls").lazyLines
// Here we use a `Seq` to make the parameter whitespace-safe
def contentsOf(dir: String): String = Seq("ls", dir).!!
ProcessBuilder
的方法分为三类:组合两个 ProcessBuilder
以创建第三类的方法,重定向 ProcessBuilder
的输入或输出的方法,以及执行与之关联的外部进程的方法。
结合ProcessBuilder
两个现有的ProcessBuilder
可以通过以下方式组合:
它们可以并行执行,第一个的输出作为输入馈送到第二个,就像 Unix 管道一样。这是通过
#|
方法实现的。它们可以按顺序执行,第二个在第一个结束后立即开始。这是通过
###
方法完成的。第二个的执行可以由第一个的返回码(退出状态)决定,或者只在它为零时,或者只在它不为零时。方法
#&&
和#||
完成这些任务。
重定向输入/输出
虽然可以在执行过程时控制输入和输出,但有一些方法可以创建具有预配置输入或输出的新 ProcessBuilder
。它们是 #<
、 #>
和 #>>
,并且可以将另一个 ProcessBuilder
(如上述管道)或其他诸如 java.io.File
或 java.io.InputStream
之类的东西作为输入。例如:
new URL("https://databinder.net/dispatch/About") #> "grep JSON" #>> new File("About_JSON") !
启动进程
要执行与 ProcessBuilder
相关的所有外部命令,可以使用四组方法之一。这些方法中的每一种都具有各种重载和变化,以实现对 I/O 的进一步控制。这些方法是:
run
:最通用的方法,它立即返回一个scala.sys.process.Process,外部命令并发执行。!
:阻塞直到所有外部命令退出,并返回执行链中最后一个的退出代码。!!
:阻塞直到所有外部命令退出,并返回带有生成输出的String
。lazyLines
:像run
一样立即返回,并且生成的输出是通过LazyList[String]
提供的。获取该LazyList
的下一个元素可能会阻塞,直到它变得可用。如果返回码不为零,此方法将引发异常 - 如果不需要,请使用lazyLines_!
方法。
处理输入和输出
如果未指定,使用run
或!
执行的外部命令的输入将不会绑定到任何东西,输出将重定向到Scala 进程的stdout 和stderr。对于方法 !!
和 lazyLines
,将不提供输入,将根据这些方法的语义定向输出。
有些方法会导致标准输入被用作输入。可以使用 scala.sys.process.ProcessLogger 控制输出 - !!
和 lazyLines
只会在传递 ProcessLogger
时重定向错误输出。如果希望完全控制输入和输出,则可以将 scala.sys.process.ProcessIO 与 run
一起使用。
例如,我们可以像这样使 lazyLines_!
的错误输出静默:
val etcFiles = "find /etc" lazyLines_! ProcessLogger(line => ())
扩展示例
让我们详细研究一个用法示例:
import scala.sys.process._
"find src -name *.scala -exec grep null {} ;" #| "xargs test -z" #&& "echo null-free" #|| "echo null detected" !
请注意,每个 String
都通过从 scala.sys.process 导入的隐式隐式转换为 ProcessBuilder
。然后以三种不同的方式组合这些ProcessBuilder
。
#|
将第一个命令的输出通过管道传输到第二个命令的输入。它反映了一个 shell 管道(|
)。#&&
如果前一个命令以退出值 0 结束,则有条件地执行第二个命令。它反映了 shell 的&&
。#||
如果前一个命令的退出值不为零,则有条件地执行第三个命令。它反映了 shell 的||
。
最后,最后的!
执行命令,并返回退出值。无论打印什么都将发送到 Scala 进程标准输出。如果我们想捕获它,我们可以使用!!
来运行它。
注意:虽然上面没有显示,但 shell 的 ;
的等价物将是 ###
。这个名字的原因是 ;
是 Scala 中的保留标记。
伴生:
- object
源码:
- ProcessBuilder.scala
相关用法
- Scala process.ProcessLogger用法及代码示例
- Scala process.urlToProcess用法及代码示例
- Scala process.fileToProcess用法及代码示例
- Scala Tabulate.sliding用法及代码示例
- Scala ArrayBuffer.inits用法及代码示例
- Scala long.BitwiseOr用法及代码示例
- Scala StringBuilder.partitionMap用法及代码示例
- Scala List distinct()用法及代码示例
- Scala DefaultMap.sizeIs用法及代码示例
- Scala StrictOptimizedIterableOps.sliding用法及代码示例
- Scala Searching.SearchResult用法及代码示例
- Scala ::.collectFirst用法及代码示例
- Scala TreeSet diff()用法及代码示例
- Scala Char getClass()用法及代码示例
- Scala int.Min用法及代码示例
- Scala IntMap.groupMap用法及代码示例
- Scala Map3.mkString用法及代码示例
- Scala IterableOnceOps.flatMap用法及代码示例
- Scala IndexedSeqOps.lengthIs用法及代码示例
- Scala Map3.addString用法及代码示例
- Scala WrappedString.scanRight用法及代码示例
- Scala String compareToIgnoreCase()用法及代码示例
- Scala List drop()用法及代码示例
- Scala ofDouble.inits用法及代码示例
- Scala SortedSet.tails用法及代码示例
注:本文由纯净天空筛选整理自scala-lang.org大神的英文原创作品 process.ProcessBuilder。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。