如何在Gradle插件中嵌入Shell脚本并在应用时运行?
Gradle插件中Shell脚本的打包与运行实现方案
一、将Shell脚本打包进插件Jar包
- 把你的Shell脚本放到插件项目的
src/main/resources/scripts目录下(目录名称可自定义,只要属于src/main/resources层级即可) - Gradle的Java插件默认会自动将
src/main/resources下的所有文件打包进最终生成的Jar包,无需额外配置。如果脚本存在于自定义路径,可通过sourceSets扩展添加资源目录:
sourceSets { main { resources { srcDirs += 'src/main/custom-scripts' // 替换为你的自定义脚本目录 } } }
二、运行时执行Jar包中的Shell脚本
Jar包内的资源无法直接作为可执行文件运行,必须先提取到本地临时文件再执行,具体实现如下:
核心逻辑
- 从Jar包中读取脚本的输入流
- 将输入流写入临时文件
- 为临时文件添加可执行权限
- 调用系统命令执行脚本
- (推荐)执行完成后自动清理临时文件
Groovy插件代码示例
class MyCustomPlugin implements Plugin<Project> { @Override void apply(Project project) { // 1. 定义一个执行脚本的任务 def runScriptTask = project.tasks.create('executeShellScript') { doLast { // 获取Jar包内的脚本资源 def scriptStream = getClass().getResourceAsStream("/scripts/your-script.sh") if (!scriptStream) { throw new GradleException("未找到指定的Shell脚本!") } // 创建临时文件,JVM退出时自动删除 def tempScript = File.createTempFile("temp-shell-script", ".sh") tempScript.deleteOnExit() // 将脚本内容写入临时文件 Files.copy(scriptStream, tempScript.toPath(), StandardCopyOption.REPLACE_EXISTING) // 设置临时文件为可执行 tempScript.setExecutable(true, false) // 执行脚本 project.exec { commandLine tempScript.absolutePath // 可选:配置输出捕获、退出值处理 standardOutput = new ByteArrayOutputStream() errorOutput = new ByteArrayOutputStream() ignoreExitValue = false // 脚本执行失败时抛出异常 } } } // 2. 可选:让脚本在插件被应用时自动执行 project.afterEvaluate { runScriptTask.execute() } } }
关键注意点
- 脚本路径要准确:
getResourceAsStream的参数以/开头,对应src/main/resources下的相对路径,比如/scripts/your-script.sh对应src/main/resources/scripts/your-script.sh - 临时文件清理:使用
deleteOnExit()确保临时文件在JVM退出时被删除,避免磁盘残留 - 权限设置:
setExecutable(true, false)表示给所有用户添加执行权限,确保脚本能被执行 - 跨平台兼容:如果需要支持Windows系统,可添加系统判断逻辑,选择执行bat脚本而非Shell脚本
内容的提问来源于stack exchange,提问作者Alexei Artsimovich
相关产品推荐
相关产品推荐

