72

I have a gradle build setup at the beginning of which I want to execute a shellscript in a subdirectory that prepares my environment.

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

build.dependsOn preBuild
preBuild.dependsOn myPrebuildTask

However, when I execute the task either by calling gradle myPrebuildTask or by simply building the project, the following error occurs:

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

Unfortunately, thats all I get.
I have also tried the following - same error.

commandLine 'sh mySubDir/myScript.sh'

I use Gradle 1.10 (needed by Android) on Windows, inside a Cygwin shell. Any ideas?

7 Answers 7

47

A more generic way of writing the exec task, but portable for Windows/Linux, if you are invoking a command file on the PATH:

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'
    }
}

This doesn't directly address the use case for the OP (since there is script file in the working directory), but the title of the question is more generic (and drew me here), so it could help someone maybe.

Sign up to request clarification or add additional context in comments.

Comments

46

use

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

your script itself is not a program itself, that's why you have to declare 'sh' as the program and the path to your script as an argument.

2 Comments

different commands for executing under linux and windows (Cygwin) are needed. I ended up supplying the scriptname as parameter: commandLine 'sh','myScript.sh'
Remember to put the task into the project gradle file and not the module gradle file.
21

unfortunately options with commandLine not worked for me in any way and my friend find other way with executable

executable "./myScript.sh"

and full task would be

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

Comments

9

This works for me in my Android project

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

See here for explanation: How to make System command calls in Java/Groovy?

Comments

5

This is a solution for Kotlin DSL (build.gradle.kts) derived from Charlie Lee's answer:

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

Another approach using the Java standard 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)
    }
}

For more information see:

Comments

2

for kotlin gradle you can use

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

Comments

-9

I copied my shell scipt to /usr/local/bin with +x permission and used it as just another command:

commandLine 'my_script.sh' 

5 Comments

This option works to, but i dont recomend put many files in /usr/local/bin
You sure you don't want to delete this answer?
If I delete, one wouldn't know how not to do it. Plus, it did work for me.
While the suggested action "works" it doesn't allow for the project to be portable and will require manual steps from anyone who needs to run the gradle build for the project.
@JoeyG I guess this can stay here. It is downvoted enough to give anyone seeking answer a hint that this recipe should be taken with caution :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.