从脚本执行SBT命令

goo*_*goo 8 bash shell scala sbt

*决定开始奖励和编辑不需要的信息

我想在SBT控制台内部运行一个脚本,该脚本将在最后运行SBT命令.如何才能做到这一点

我写了一个允许我执行shell命令的脚本.键入sbt然后path/to/my-script start给我这个错误:/bin/sh: start command not found

path/to/my-script sbt start工作正常

在这种情况下,sbt插件(例如这些)或自定义任务不起作用的原因:

  • 该脚本不是用scala编写的

快速编辑

*我更喜欢start从脚本执行而不是使用自定义任务/命令来运行我的脚本

更多信息如下


我将逐步解释我想做什么(我正在做的事可能听起来很愚蠢,但请阅读我对Etan的回应):

  1. 在我的控制台中键入sbt,它将调用SBT控制台

  2. 而不是打字start,我想运行一个脚本,它将执行与项目没有直接关系的其他东西,然后start在完成时调用.

由于不太熟悉脚本,脚本可以调用#!/bin/sh命令,所以我想我想要做的是调用一个#!/bin/sh/<*this-sbt-console*>命令,如果可能的话

即使是一种解决方法,如果我可以让脚本只start在终端上打印并enter/return在完成后调用密钥,就足够了

其他信息:

  • 不使用任何特定框架
  • SBT版本= 0.13+

Fer*_*eia 12

为了能够执行脚本,并在该脚本完成后继续执行另一个sbt命令,一种方法是实现自定义sbt命令,该命令执行以下操作:

  1. 执行作为其第一个参数提供的外部进程,将任何其他参数传递给此进程.
  2. 等待外部流程完成.
  3. 外部进程完成后,执行另一个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
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个示例执行:

$ 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.
> 
Run Code Online (Sandbox Code Playgroud)

作为参数传递的外部命令customStart可以是任何可执行命令,例如二进制文件或shell脚本.

要了解有关创建命令的更多信息,请参阅命令文档页面.

要了解有关执行外部进程的更多信息,请参阅外部进程文档页面.

完整示例可从此GitHub存储库下载.

由于sbt执行脚本(作为子进程),该脚本无法在原始(父)sbt进程上执行命令.

可以将脚本的输出捕获stdout到文件或文件,并让sbt命令执行脚本生成的任意命令,但这有点令人费解.

另一种方法是颠倒执行顺序.而不是sbt执行脚本,脚本将首先直接从shell执行,脚本将执行sbt命令.

例如,这个脚本:

#!/bin/bash
echo "Running custom script"
# Insert commands here
sbt start
Run Code Online (Sandbox Code Playgroud)

生成此输出:

$ ./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.
Run Code Online (Sandbox Code Playgroud)