Groovy脚本中如何在单个进程执行多条Shell命令?
在Groovy脚本的单个Shell进程中执行多条命令的解决方案
你的问题出在Groovy的String.execute()默认行为上——它不会自动通过shell解析命令序列,而是把整个字符串当作单个命令(或拆分后当作命令+参数),所以cd只是单独启动了一个进程,执行完就退出,后面的npm pack和tar会在原来的工作目录下执行,自然达不到预期效果。
要让多条命令在同一个Shell进程里执行,有两种可靠的方案:
方案1:通过Shell解析命令序列
明确调用系统Shell(比如bash或sh),用-c参数传递完整的命令串,这样Shell会帮你解析&&连接的命令,并且cd的目录切换会作用于后续命令。
Groovy里可以用三重引号避免引号转义的麻烦:
def cmd = """bash -c 'cd .composerpages/umanagement && npm pack @mag-umanagement/umanagement-pages-v2810@^28.10.4-SNAPSHOT && tar xvzf *.tgz'""" def process = cmd.execute() // 建议等待命令执行完成并检查结果 process.waitFor() if (process.exitValue() != 0) { println "执行失败:${process.err.text}" } else { println "执行成功:${process.in.text}" }
方案2:指定工作目录(更可靠的Groovy风格)
其实没必要用cd,Groovy的execute()方法支持直接指定命令的工作目录,这样所有命令都在目标目录下执行,避免依赖Shell的行为,代码更可控:
// 定义目标工作目录 def workingDir = new File(".composerpages/umanagement") // 执行npm pack,指定工作目录 def packProcess = ["npm", "pack", "@mag-umanagement/umanagement-pages-v2810@^28.10.4-SNAPSHOT"].execute(null, workingDir) packProcess.waitFor() // 等待打包完成再执行解压 if (packProcess.exitValue() != 0) { println "npm pack失败:${packProcess.err.text}" return } // 执行tar解压,同样指定工作目录 def tarProcess = ["tar", "xvzf", "*.tgz"].execute(null, workingDir) tarProcess.waitFor() if (tarProcess.exitValue() != 0) { println "解压失败:${tarProcess.err.text}" } else { println "操作完成" }
这个方案的好处是:
- 不需要依赖Shell的命令解析,跨平台兼容性更好
- 可以分别处理每个命令的执行结果,更容易排查问题
- 明确等待前一个命令完成再执行下一个,避免
tar尝试解压还没生成的.tgz文件
内容的提问来源于stack exchange,提问作者Rainer Feike
相关产品推荐
相关产品推荐

