如何将 shell 脚本 (bash) 转换为 Scala 代码?
How to convert a shell script (bash) to Scala code?
我有一个 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 代码?
根据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
更改当前目录,也不能使用 bash 语法,例如if
, for
, case
.
如果你真的想要 bash 等效代码,唯一的方法是 运行 将脚本与 bash 结合起来。
除了 ###
方法之外,正如@ymonad 指出的那样,您真的应该更直接地使用 ProcessBuilder
方法。它使代码更易于阅读和理解。
import sys.process._
Seq("mkdir", "SO") ###
Seq("touch", "SO/file") ###
Seq("mv", "SO", "SoWhat") !
在解析传递给进程的多个参数时,使用 Seq[String]
代替简单的 String
提供 。
我没有深入研究这个项目,所以我无法通过第一手示例帮助您,但请看一下 Ammonite Scala project。
引用自主页:
Ammonite lets you use the Scala language for scripting purposes: in the REPL, as scripts, as a library to use in existing projects, or as a standalone systems shell.
...
The goal of Ammonite is to liberate your Scala code from heavyweight "projects", using the lightweight Ammonite runtime: if you want to run some Scala, open the Ammonite-REPL and run it, interactively! If you want to run it later, save it into some Scala Scripts and run those later.
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:
我有一个 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 代码?
根据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
更改当前目录,也不能使用 bash 语法,例如if
, for
, case
.
如果你真的想要 bash 等效代码,唯一的方法是 运行 将脚本与 bash 结合起来。
除了 ###
方法之外,正如@ymonad 指出的那样,您真的应该更直接地使用 ProcessBuilder
方法。它使代码更易于阅读和理解。
import sys.process._
Seq("mkdir", "SO") ###
Seq("touch", "SO/file") ###
Seq("mv", "SO", "SoWhat") !
在解析传递给进程的多个参数时,使用 Seq[String]
代替简单的 String
提供
我没有深入研究这个项目,所以我无法通过第一手示例帮助您,但请看一下 Ammonite Scala project。
引用自主页:
Ammonite lets you use the Scala language for scripting purposes: in the REPL, as scripts, as a library to use in existing projects, or as a standalone systems shell.
...
The goal of Ammonite is to liberate your Scala code from heavyweight "projects", using the lightweight Ammonite runtime: if you want to run some Scala, open the Ammonite-REPL and run it, interactively! If you want to run it later, save it into some Scala Scripts and run those later.
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: