scala調用系統-scala.sys.process使用

簡介html

scala.sys.process提供了shell的和系統交互的DSL,包括執行命令, 邏輯操做, 重定向, 管道等操做。java

啓動流程
要執行與ProcessBuilder關聯的全部外部命令,scala.sys.process提供了四組方法中。 這些方法中的每一種都具備各類過載和變化,以實現對I/O的進一步控制。
這四種方法以下:linux

  • run:最通用的方法,它當即返回一個scala.sys.process.Process,而且外部命令同時執行。
"find /tmp -name *.jar".run()
  • !:阻塞,直到全部外部命令退出,並返回執行鏈中最後一個的退出代碼
"find /tmp -name *.jar" !

若是沒有參數,直接輸出到標準輸出或者標準錯誤輸出. 同時能夠傳遞Logger參數給!.

import scala.sys.process._
var normalLines = 0
var errorLines = 0
val countLogger = ProcessLogger(line => normalLines += 1,line => errorLines += 1)
"find /etc" ! countLogger
保存到變量中(返回最後命令運行的狀態)
val result: Int = "find /tmp -name *.jar" !
  • !!:阻塞直到全部外部命令都退出,並返回一個生成輸出的String。
"find project -name *.jar".!!
保存到變量中(保存輸出內容)
val result :String = "find project -name *.jar" !!
  • lineStream:像run同樣當即返回,生成的輸出經過Stream [String]提供。

獲取該流的下一個元素可能會阻塞,直到它變爲可用。 若是返回碼不爲零,此方法將拋出異常shell

val contents: Stream[String] = Process("ls").lineStream

注:若是不須要,請使用lineStream_! 方法。ruby

val etcFiles = "find /etc" lines_! ProcessLogger(line => ())

處理輸入和輸出網絡

  • 若是未指定,則使用run或!執行外部命令的輸入。 不會綁定任何東西,輸出將被重定向到Scala進程的stdout和stderr。
  • 對於方法!! 和lines,不提供輸入,輸出將根據這些方法的語義進行定向。

Combining ProcessBuilder

這些ProcessBuilder以三種不一樣的方式組合。ui

  • #|      將第一個命令的輸出傳遞給第二個命令的輸入。 它鏡像一個shell管(|)
  • #&&  有條件地執行第二個命令,若是前一個命令以退出值0結束。它鏡像shell的&&
  • #||     若是前一個命令的退出值不爲零,則有條件地執行第三個命令。 它鏡像shell的||

例如:url

它們能夠並行執行,第一個輸出做爲輸入提供給第二個,就像Unix管道同樣。 這是經過#|實現的方法。spa

"ls" #| "grep linux"

它們能夠按順序執行,第二次結束後第二次啓動。 這是經過###方法完成的。.net

"ls" ### "grep linux"

第二個的執行能夠經過第一個的返回代碼(退出狀態)來調節,或者僅在它爲零時,或者僅在它不爲零時。 方法 #&& 和 #|| 完成這些任務

import scala.sys.process._
"find src -name *.scala -exec grep null {} ;" #| "xargs test -z" #&& "echo null-free" #|| "echo null detected" !

重定向
scala的重定向不只能夠從定向普通的文件,還能夠把網絡上的文件進行重定向到本地:

a #< url or url #> a
例子:
url("http://fuliang.iteye.com") #> file("blog.html") !
或者
file("blog.html") #< url("http://fuliang.iteye.com") !
注: 示例中的url和file均需進行封裝,具體以下:
new java.net.URL("http://www.baidu.com") #> new java.io.File("/tmp/baidu.html") !

注意,重定向必須用 new java.io.File("")封裝,不然會看成命令,好比"ls" #> "/tmp/a" !將會出錯,必須scala> "ls" #> new java.io.File("/tmp/a") !

文件:

a #< file or file #> a
a能夠是一個文件或者一個命令,好比:
file("blog.html") #> file("fuliang_blog.html") !
或者
file("fuliang_blog.html") #< file("blog.html") !

追加操做 #>>, #<<

a #>> file or file #<<
url("http://fuliang.iteye.com") #> "grep -i ruby" #>> file("Ruby") !
或者
file("Ruby") #<< ( "grep ruby" #< url(http://fuliang.iteye.com") ) !

與cat一塊兒使用

val spde = url("http://technically.us/spde/About")
val dispatch = url("http://databinder.net/dispatch/About")
val build = file("project/build.properties")
cat(spde, dispatch, build) #| "grep -i scala" ! 

最後:! 最後執行命令,並返回退出值。 不管打印什麼都將發送到Scala過程標準輸出。 若是咱們想捕捉它,咱們能夠用 !! 代替

注意:lines方法雖然已棄用,但可能與同名的StringLike方法衝突。 爲避免這種狀況,可能但願在進程中調用構建器而不是導入scala.sys.process._。 上面的例子是import scala.sys.process.ProcessProcess("find src -name *.scala -exec grep null {} ;") #| Process("xargs test -z") #&& Process("echo null-free") #|| Process("echo null detected") !

相關文章
相關標籤/搜索