我需要为不熟悉scala(既不是Java)但熟悉Shell的用户开发API.他们基本上会在scala类中编写shell脚本(我知道我可以调用外部shell脚本,但是来吧!另外,稍后我们将为常见的shell任务提供一些函数).
我希望能够完成以下事情:
1 object MyCoolScript extends MyMagicTrait {
2 $ "mkdir /tmp/test"
3 $ "cd /tmp/test"
4 $ "wget some-url"
5 }
Run Code Online (Sandbox Code Playgroud)
更直接,我如何将第2-4行(或可能不那么简洁的版本)转换为我可以在MyMagicTrait中处理的Seq [String]?
我知道sys.process.stringToProcess但是如果我有:
object MyCoolScript extends MyMagicTrait {
"mkdir /tmp/test" !!
"cd /tmp/test" !!
"wget some-url" !!
}
Run Code Online (Sandbox Code Playgroud)
如何以简洁的方式获得每个命令的结果?另外,我希望有一个$"xxx"表示法.
发布回答更新:
感谢@debilski,@ atensi和@ daniel-c-sobral,我能够非常接近所需的实现:https://gist.github.com/2777994
class Shell {
var elems = Vector[String]()
def >(str: String) = elems :+= str
def run() = elems.map( whatever )
}
val shell = new Shell
shell> "mkdir /tmp/test.dir"
shell> "cd /tmp/test.dir"
Run Code Online (Sandbox Code Playgroud)
看来 Scala 2.10 附带的字符串插值可以帮助你。首先,您可以实现简单的$方法,即立即执行命令。为了做到这一点,您需要添加此自定义方法StringContext:
object ShellSupport {
implicit class ShellStrings(sc: StringContext) {
def $(args: Any*) =
sc.s(args: _*) split "\n" map (_.trim) filterNot (_.isEmpty) foreach { cmd =>
// your excution logic goes here
println(s"Executing: $cmd")
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以像这样使用它:
import ShellSupport._
val testDir = "/tmp/test"
$"mkdir $testDir"
$"cd $testDir"
$"""
wget some-url
wget another-url
"""
Run Code Online (Sandbox Code Playgroud)
您可以利用它的语法(唯一的缺点是您不能在$and之间添加空格")和命令内的字符串插值。
现在让我们尝试实现你的魔法特质。通常是相同的想法,但我也使用它DelayedInit来正确定义命令,然后在类创建期间自动执行它们。
trait MyMagicTrait extends DelayedInit {
private var cmds: List[String] = Nil
def commands = cmds
implicit class ShellStrings(sc: StringContext) {
def $(args: Any*) = {
val newCmds = sc.s(args: _*) split "\n" map (_.trim) filterNot (_.isEmpty)
cmds = cmds ++ newCmds
}
}
def delayedInit(x: => Unit) {
// your excution logic goes here
x
cmds map ("Excutintg: " + _) foreach println
}
}
Run Code Online (Sandbox Code Playgroud)
它的用法:
class MyCoolScript extends MyMagicTrait {
val downloader = "wget"
$"mkdir /tmp/test"
$"cd /tmp/test"
$"""
$downloader some-url
$downloader another-url
"""
}
new MyCoolScript
Run Code Online (Sandbox Code Playgroud)
这两种解决方案都会产生相同的输出:
Executing: mkdir /tmp/test
Executing: cd /tmp/test
Executing: wget some-url
Executing: wget another-url
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1010 次 |
| 最近记录: |