我有一个带有一系列定义步骤的shell脚本。我试图通过保持步骤顺序将脚本转换为Scala代码。基本上,我希望Scala代码成为Shell脚本的镜像。
我已经使用了 sys.process ._ 库。 Shell脚本具有以下命令:
mkdir <pathToDir>
hadoop fs -copyToLocal <source> <dest>
rm -r <pathToDir>
java -jar <someScript>
我需要保持这些步骤的执行顺序。
我尝试了以下方法:
import sys.process._
Class A {
def processMethod(): Unit = {
Process("mkdir -p <dir1>") #| Process("hadoop fs -copyToLocal
<hdfsDir1> <localDir1>") #| Process("mkdir -p <dir2>") #|
Process("hadoop fs -copyToLocal <hdfsdir2>/*.parquet <localDir2>")
#| Process("java -jar <pathToJarFile> -script <sampleScripts> 1>&2")
#| Process("rm -r<localDir1>") #| Process("rm -r <localDir2>") !
}
}
我期望这些操作按照定义的顺序执行。我对ProcessBuilder / Process的工作方式感到困惑,或者是否存在将整个内容转换为Scala代码的替代方法?
答案 0 :(得分:3)
根据document,#|
构造了一个命令,该命令将运行命令并将输出通过管道传递给其他命令。
就是说,Scala中的以下代码:
(Process("echo hello") #| Process("wc -c")).!
等效于以下Bash代码:
echo hello | wc -c
这不是您想要的。
您正在寻找的是###运算符,该运算符构造了一个命令,该命令将先运行一个命令,然后再运行另一个命令。
使用此运算符,您可以编写以下Scala代码:
(Process("ls") ### Process("echo hello")).!
等同于以下Bash代码:
ls
echo hello
但是,请注意,以上述方式使用Process
并不完全等同于bash,因为它无法使用cd
更改当前目录,也无法使用if
,{{1}等bash语法},for
。
如果您真的想要bash等效代码,唯一的方法是使用bash运行脚本。
答案 1 :(得分:2)
正如@ymonad指出的那样,除了###
方法之外,您实际上应该更直接地使用ProcessBuilder
方法。它使代码更易于阅读和理解。
import sys.process._
Seq("mkdir", "SO") ###
Seq("touch", "SO/file") ###
Seq("mv", "SO", "SoWhat") !
在解析传递给流程的多个参数时,使用Seq[String]
代替简单的String
提供some advantages。
答案 2 :(得分:2)
我没有深入研究这个项目,因此我无法为您提供第一手示例,但请看一下Ammonite Scala project。
从主页报价:
Ammonite允许您将Scala语言用于脚本编写目的:在REPL中,作为脚本,作为在现有项目中使用的库,或作为独立的系统外壳。
...
Ammonite的目标是使用轻量级的Ammonite运行时从重量级的“项目”中解放您的Scala代码:如果要运行某些Scala,请打开Ammonite-REPL并以交互方式运行它!如果要稍后运行,请将其保存到一些Scala脚本中并稍后运行。
At this link是您可以做什么的一些示例:
import ammonite.ops._
// Let's pick our working directory
val wd: Path = pwd/'ops/'target/"scala-2.11"/"test-classes"/'example3
// And make sure it's empty
rm! wd
mkdir! wd
// You can create folders through `mkdir!`. This behaves the same as
// `mkdir -p` in Bash, and creates and parents necessary
val deep = wd/'this/'is/'very/'deep
mkdir! deep
// You can also use backticks to execute commands which aren't valid Scala identifiers, e.g.
`ssh-add`
Enter passphrase for /Users/haoyi/.ssh/id_rsa: