* 决定开始赏金&编辑出不需要的信息
我想在SBT控制台内部运行一个脚本,该脚本最后会运行SBT命令。如何做到这一点
我编写了一个允许我执行shell命令的脚本。输入sbt
然后path/to/my-script start
会输入错误:/bin/sh: start command not found
但是path/to/my-script sbt start
工作正常
sbt插件(例如these)或自定义任务在这种情况下不起作用的原因:
快速修改
*我更喜欢从脚本执行start
而不是使用自定义任务/命令来运行我的脚本
我会一步一步解释我想做什么(我正在做的事对你来说可能听起来很傻,但请阅读我对Etan的回应):
在我的控制台中键入sbt,它将调用SBT控制台
我不想输入start
,而是要运行一个脚本,该脚本将执行与项目无直接关系的其他内容,然后为我调用start
什么时候完成。
对脚本不太熟悉,脚本可以调用#!/bin/sh
命令,所以我想我想要做的是调用#!/bin/sh/<*this-sbt-console*>
命令(如果可能的话)
即使是一种解决方法,如果我可以让脚本只在终端上打印start
并在完成后调用enter/return
键就足够了
其他信息:
答案 0 :(得分:11)
为了能够执行脚本,并在该脚本完成后继续执行另一个sbt命令,一种方法是实现自定义sbt命令,该命令执行以下操作:
这在Build.scala
文件中进行了演示:
import sbt._
import Keys._
// imports standard command parsing functionality
import complete.DefaultParsers._
object CommandExample extends Build {
// Declare a project, adding new commands.
lazy override val projects = Seq(root)
lazy val root = Project("root", file(".")) settings(
commands ++= Seq(start, customStart)
)
// A fake "start" command.
def start = Command.command("start") { state =>
println("Fake start command executed.")
state
}
// A command that executes an external command before executing the "start" command.
// The name of the external command is the first parameter.
// Any additional parameters are passed along to the external command.
def customStart = Command.args("customStart", "<name>") { (state, args) =>
if (args.length > 0) {
val externalCommand = args.mkString(" ")
println(s"Executing '$externalCommand'")
externalCommand !
}
"start" :: state
}
}
这是一个示例执行:
$ sbt
[info] Loading project definition from /home/fernando/work/github/fernandoacorreia/so24565469/project
[info] Set current project to hello (in build file:/home/fernando/work/github/fernandoacorreia/so24565469/)
> customStart ls -la
Executing 'ls -la'
total 40
drwxr-xr-x 6 fernando fernando 4096 Jul 8 10:52 .
drwxr-xr-x 27 fernando fernando 4096 Jul 8 08:51 ..
-rw-r--r-- 1 fernando fernando 95 Jul 8 10:47 build.sbt
drwxr-xr-x 8 fernando fernando 4096 Jul 8 08:58 .git
-rw-r--r-- 1 fernando fernando 203 Jul 8 09:04 .gitignore
-rw-r--r-- 1 fernando fernando 1082 Jul 8 08:51 LICENSE
drwxr-xr-x 3 fernando fernando 4096 Jul 8 10:51 project
-rw-r--r-- 1 fernando fernando 111 Jul 8 08:51 README.md
drwxr-xr-x 3 fernando fernando 4096 Jul 8 08:57 src
drwxr-xr-x 2 fernando fernando 4096 Jul 8 10:52 target
Fake start command executed.
>
作为参数传递给customStart
的外部命令可以是任何可执行命令,例如,二进制文件或shell脚本。
要了解有关创建命令的更多信息,请参阅Commands documentation page。
要了解有关执行外部流程的更多信息,请参阅External Processes documentation page。
完整示例可在this GitHub repository下载。
由于sbt执行脚本(作为子进程),该脚本无法在原始(父)sbt进程上执行命令。
可以将脚本的输出捕获到stdout
或文件,并让sbt命令执行脚本生成的任意命令,但这有点回旋。
另一种方法是颠倒执行顺序。而不是让sbt
执行脚本,脚本将首先直接从shell执行,脚本将执行sbt命令。
例如,这个脚本:
#!/bin/bash
echo "Running custom script"
# Insert commands here
sbt start
生成此输出:
$ ./script
Running custom script
[info] Loading project definition from /home/fernando/work/github/fernandoacorreia/so24565469/project
[info] Set current project to hello (in build file:/home/fernando/work/github/fernandoacorreia/so24565469/)
Fake start command executed.
答案 1 :(得分:2)
如你所说“有没有办法告诉脚本在终端上写东西并按回车/输入?”
是的 - 稍微苛刻但非常有效的解决方案是一个名为 expect 的小程序。
http://www.thegeekstuff.com/2010/10/expect-examples/
http://www.admin-magazine.com/Articles/Automating-with-Expect-Scripts
它会让您通过键盘执行任何操作,但会自动执行。它就像UNIX命令提示符的宏播放引擎。