在Gradle中执行shell脚本

问题描述 投票:0回答:7

我有一个 gradle 构建设置,在它的开头我想在准备环境的子目录中执行 shell 脚本。

task build << {
}
task preBuild << {
    println 'do prebuild stuff:'
}
task myPrebuildTask(type: Exec) {
    workingDir "$projectDir/mySubDir"
    commandLine './myScript.sh'
}

build.dependsOn preBuild
preBuild.dependsOn myPrebuildTask

但是,当我通过调用

gradle myPrebuildTask
或简单地构建项目来执行任务时,会出现以下错误:

> A problem occurred starting process 'command './myScript.sh''

不幸的是,这就是我所得到的。
我也尝试过以下 - 同样的错误。

commandLine 'sh mySubDir/myScript.sh'

我在 Windows 上的 Cygwin shell 中使用 Gradle 1.10(Android 需要)。有什么想法吗?

android gradle cygwin
7个回答
46
投票

使用

commandLine 'sh', './myScript.sh'

您的脚本本身不是程序本身,这就是为什么您必须将“sh”声明为程序并将脚本的路径声明为参数。


45
投票

如果您在 PATH 上调用命令文件,则编写 exec 任务的更通用方法,但对于 Windows/Linux 来说是可移植的:

task myPrebuildTask(type: Exec) {
    workingDir "$projectDir/mySubDir"
    if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
        commandLine 'cmd', '/c', 'mycommand'
    } else {
        commandLine 'sh', '-c', 'mycommand'
    }
}

这并没有直接解决OP的用例(因为工作目录中有脚本文件),但问题的标题更通用(并吸引了我在这里),所以它可能可以帮助某人。


18
投票

不幸的是,commandLine的选项对我来说没有任何作用,我的朋友通过executable

找到了其他方法
executable "./myScript.sh"

完整的任务是

task startScript() {
  doLast {
     exec {
          executable "./myScript.sh"
      }
  }
}

9
投票

这对我的 Android 项目有用

preBuild.doFirst {
    println("Executing myScript")
    def proc = "mySubDir/myScript.sh".execute()
    proc.waitForProcessOutput(System.out, System.err)
}

请看这里的解释: 如何在Java/Groovy中进行系统命令调用?


4
投票

这是 Kotlin DSL (build.gradle.kts) 的解决方案,源自 Charlie Lee 的回答

task<Exec>("MyTask") {
    doLast {
        commandLine("git")
            .args("rev-parse", "--verify", "--short", "HEAD")
            .workingDir(rootProject.projectDir)
    }
}

使用 Java 标准 ProcessBuilder API 的另一种方法:

tasks.create("MyTask") {
    val command = "git rev-parse --verify --short HEAD"
    doLast {
        val process = ProcessBuilder()
            .command(command.split(" "))
            .directory(rootProject.projectDir)
            .redirectOutput(Redirect.INHERIT)
            .redirectError(Redirect.INHERIT)
            .start()
        process.waitFor(60, TimeUnit.SECONDS)
        val result = process.inputStream.bufferedReader().readText()
        println(result)
    }
}

欲了解更多信息,请参阅:


2
投票

对于 kotlin gradle,你可以使用

 Runtime.getRuntime().exec("./my_script.sh")

-10
投票

我将 shell scipt 复制到

/usr/local/bin
并具有
+x
权限,并将其用作另一个命令:

commandLine 'my_script.sh' 
© www.soinside.com 2019 - 2024. All rights reserved.