Gradle exec 任务失败并显示“execCommand == null!”

ret*_*ius 6 gradle

我的build.gradle文件中有以下任务:

task myTask(type:Exec) {
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'cmd', '/c', 'whoami'
        standardOutput = stdout;
    }
    println "Output: $stdout"
}
Run Code Online (Sandbox Code Playgroud)

当我用 运行我的任务时./gradlew myTask,我得到以下输出:

> Configure project :
Output: retrovius


> Task :myTask FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':myTask'.
> execCommand == null!

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s
1 actionable task: 1 executed
Run Code Online (Sandbox Code Playgroud)

该任务成功输出了我的用户名(retrovius),但还是失败了。关于我做错了什么的任何指示?

Bjø*_*ter 6

根据您想要实现的目标,您找到的答案可能仍然不正确。

所有任务都有两个主要阶段:配置和执行。您在任务定义的最外层块中放置的所有内容都是配置的一部分。exec每当评估该代码块时,该方法实际上都会执行该命令。所以当你输入:

task myTask() {
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'cmd', '/c', 'whoami'
        standardOutput = stdout;
    }
    println "Output: $stdout"
}
Run Code Online (Sandbox Code Playgroud)

那么这意味着whoami无论您指定什么任务,您都在运行该命令。如果您运行gradle -i help,它将打印名称。我希望这不是你想要的。

大多数情况下,您只希望在实际执行任务时运行命令。因此,如果您希望命令仅在键入时运行gradle -i myTask,则需要将其推迟到执行阶段。有两种方法可以做到这一点。

您可以将所有内容放在这样的doLast块中:

task myTask() {
    doLast {
        def stdout = new ByteArrayOutputStream()
        exec {
            commandLine 'cmd', '/c', 'whoami'
            standardOutput = stdout
        }
        println "Output: $stdout"
    }
}
Run Code Online (Sandbox Code Playgroud)

或者您使用Exec type,就像您已经尝试过的那样。它对您不起作用的原因是您需要使用您喜欢的命令对其进行配置- 而不是通过该方法实际运行该命令exec。它可能看起来像这样:

task myTask(type: Exec) {
    commandLine 'cmd', '/c', 'whoami'
    standardOutput = new ByteArrayOutputStream()
    doLast {
        println "Output: $standardOutput"
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可能摆脱了这个cmd /c部分。并且println应该仅用于调试 -如果您需要向用户输出某些内容,请使用logger.info(或.warn等)。


ret*_*ius 5

我发现我唯一做错的就是将 包含(type:Exec)在我的任务定义中。如果我将以下代码放入我的build.gradle文件中:

task myTask() {
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'cmd', '/c', 'whoami'
        standardOutput = stdout;
    }
    println "Output: $stdout"
}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

> Configure project :
Output: retrovius


BUILD SUCCESSFUL in 2s
Run Code Online (Sandbox Code Playgroud)

我的错误一定是我将任务定义为 exec 类型,但没有给它运行命令。这揭示了我对 exec 任务和任务类型的根本误解。如果有人更具体地知道我做错了什么,请随时发表评论和解释或发布更好的答案。