【问题标题】:Running shell command from Gradle script从 Gradle 脚本运行 shell 命令
【发布时间】:2017-10-26 16:52:16
【问题描述】:

我正忙着弄清楚如何从 Gradle 运行 shell 命令,因为 Gradle 似乎很难做到这一点。

命令如下:

git branch --merged | grep -v \* | grep -v master | grep -v develop | grep -v dmz | xargs git branch -D

这只是一个方便的命令来清理已经合并的本地分支。

这是我创建的任务:

task gitCleanLocalBranches {
    doLast {
        exec {
            workingDir '.'
            commandLine 'git branch --merged | grep -v \\* | grep -v master | grep -v develop | grep -v dmz | xargs git branch -D'

        }
    }
}

任务失败:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':gitCleanLocalBranches'.
> A problem occurred starting process 'command 'git branch -a''

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':gitCleanLocalBranches'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
        ...
Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command 'git branch --merged | grep -v \* | grep -v master | grep -v develop | grep -v dmz | xargs git branch -D''
        at org.gradle.process.internal.DefaultExecHandle.execExceptionFor(DefaultExecHandle.java:222)
        ... 3 more
Caused by: net.rubygrapefruit.platform.NativeException: Could not start 'git branch --merged | grep -v \* | grep -v master | grep -v develop | grep -v dmz | xargs git branch -D'
        at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:27)
        ... 4 more
Caused by: java.io.IOException: Cannot run program "git branch --merged | grep -v \* | grep -v master | grep -v develop | grep -v dmz | xargs git branch -D" (in directory "/home/wlaw/sterlib"): error=2, No such file or directory
        at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)
        ... 6 more
Caused by: java.io.IOException: error=2, No such file or directory
        ... 7 more

所以我认为命令太复杂所以我尝试了一些更简单的东西,并将commandLine更改为:

commandLine 'git branch -a'

但我得到了完全相同的错误。为什么 Gradle 无法在 PATH 环境变量中找到任何内容?

【问题讨论】:

    标签: shell gradle


    【解决方案1】:

    要执行的命令及其参数必须是单独的参数才能传递给commandLine,如下所示:

    commandLine 'git', 'branch', '-a'
    

    如果您想像第一个示例一样执行复杂的管道, 您可以将其包装在 shell 脚本中。

    我无法对此进行测试,但我认为这应该也可以:

    commandLine 'sh', '-c', 'git branch --merged | grep -v -e \* -e master -e develop -e dmz | xargs git branch -D'
    

    注意:我冒昧地简化了grep

    最后,您还可以在 .gitconfig 中创建一个 Git 别名来包装复杂的管道。

    【讨论】:

    • 首先,这确实很烦人,而且看起来不必要地复杂,尤其是对于带有许多参数的单个命令。但是对于您的第二点,那是一种希望我不必做的事情,因为这实际上只是一个衬里,因此制作一个全新的文件似乎可以回避 Gradle 的问题,即无法仅从其中运行 shell 命令在 build.gradle 中。
    • re:只需运行一个 shell 命令。在 Unix 中,管道用于分隔多个命令。如果你愿意,你可以称它为单行,但它仍然代表多个命令。
    • @wheeler 我在我的答案中添加了两个可能适合您的替代方案。
    【解决方案2】:

    如果您需要保存命令输出,您可以这样做:

    def gitBranchA = "git branch -a".execute().text.trim()
    

    【讨论】: