我的 build.gradle 文件中有以下任务:
task myTask(type:Exec) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
使用./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
任务成功输出了我的用户名(retrovius),但无论如何还是失败了。关于我在做什么的任何指示?
答案 0 :(得分:2)
根据您要实现的目标,找到的答案可能仍然不正确。
所有任务都有两个主要阶段:配置和执行。您在任务定义的最外面的块中放置的所有内容都是配置的一部分。每当评估该代码块时,exec
方法实际上就会执行命令。所以当您输入:
task myTask() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
这意味着无论您指定什么任务,您都在运行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"
}
}
或者您已经尝试过使用Exec
类型。它对您不起作用的原因是您需要使用所需的命令进行配置-而不是实际上通过exec
方法运行 。看起来可能像这样:
task myTask(type: Exec) {
commandLine 'cmd', '/c', 'whoami'
standardOutput = new ByteArrayOutputStream()
doLast {
println "Output: $standardOutput"
}
}
您也可能会摆脱cmd /c
部分。并且println
仅应用于调试-如果需要向用户输出某些内容,请使用logger.info
(或.warn
等)。
答案 1 :(得分:0)
我发现我做错的唯一一件事就是在任务定义中包含(type:Exec)
。如果我将以下代码放在我的 build.gradle 文件中:
task myTask() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
我得到以下输出:
> Configure project :
Output: retrovius
BUILD SUCCESSFUL in 2s
我的错误一定是我将任务定义为exec类型,但没有给它运行命令。这表明我对exec任务和任务类型有根本的误解。如果有人更清楚地知道我做错了什么,请随时发表评论,解释或发布更好的答案。