Gradle 在自定义任务中执行命令行

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

在我的 gradle 文件中,我定义了以下任务:

task text_example <<
{
   //?!? commandLine ''
   println 'Fam Flinstone'
}

我想在这个任务中放入一些命令行。我怎样才能做到这一点?

我正在使用一个库自动在 Google Play 中发布。我的项目基于产品风味,我需要为我的每一种风味逐个命令行传递终端命令行。所以我想传递

test_example
任务中的所有命令行。

android gradle gradle-task
2个回答
69
投票

您基本上有两个主要方便的选择:

  1. 使用 Gradle Exec 任务类型

     task fooExec(type: Exec) {
         workingDir "${buildDir}/foo"
         commandLine 'echo', 'Hello world!'
         doLast {
             println "Executed!"
         }
     }
    
  2. 使用 Gradle Project.exec 方法

     task execFoo {
         doLast {
             exec {
                 workingDir "${buildDir}/foo"
                 executable 'echo'
                 args 'Hello world!'
             }
             println "Executed!"
         }
     }
    

在闭包内的两种情况下,您都可以使用 ExecSpec 的方法指定执行参数。 执行命令的标准输出和错误输出将被重定向到 gradle 进程的 stdout 和 stderr。

编辑@2022-07-07

下面的评论中提到了一个重要的警告:Gradle 的

exec
会像 shell(例如 Linux 上的 Bash 或 Windows 上的 CMD)那样评估命令行,它只是使用提供的参数执行指定的可执行文件。

这有一些需要牢记的隐藏的后果:

  1. 要执行“命令”,需要指定一个有效的现有可执行文件。

    出现这种情况的最常见情况是尝试使用由 shell 在特定操作系统上实现的“命令”,并且没有可执行文件形式的可用实现(例如

    echo
    和类似的命令) Windows)。

  2. 现代 shell 不支持流重定向等“花哨”功能(尽管您仍然可以使用自定义 IO 配置的两个单独的 exec 调用将一个进程的 stdout 重定向到另一个进程的

    stdin
    )。

  3. 用户定义的别名(例如在

    ~/.bsahrc
    中定义)可用。

FIY:实际上不要这样做!

在 Gradle 中“轻松”获得现代 shell 功能的“常见”解决方法是实际运行 shell 进程并提供命令行作为其参数,例如如果使用 Bash:

task shellExec(type: Exec) {
    workingDir "${buildDir}/foo"
    commandLine 'bash', '-c', "echo 'Hello world!'"
}

但是,这种方法会立即将构建脚本绑定到特定平台,使其无法在没有该特定 shell 的平台上运行(例如上面的示例在 Windows 上不起作用)。


0
投票

在 Gradle Kotlin 插件中,你可以这样做:

    afterEvaluate {
      val process = Runtime.getRuntime().exec("whoami")
        process.inputStream.bufferedReader().useLines { lines ->
          println("User: ${lines.first()}
        }
      }
    }

https://docs.gradle.org/current/dsl/org.gradle.api.tasks.JavaExec.html

© www.soinside.com 2019 - 2024. All rights reserved.