用法 一
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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。