Jenkinsfile中执行含括号的shell通配命令报错如何解决
Jenkinsfile中扩展通配符执行失败解决方案
核心原因
所有报错本质来自两个问题:
- Jenkins
sh步骤默认调用/bin/sh执行命令,绝大多数Linux发行版中/bin/sh指向dash等POSIX标准shell,不支持bash专属的extglob扩展通配能力。!(pattern)这类排除匹配规则属于extglob特性,未开启支持时shell会将(识别为非法语法标记,直接抛出语法错误。 - Groovy字符串转义与shell转义双层叠加时,手动转义括号极易出现转义失效,最终通配符被解析为普通文件名字符串,触发文件不存在报错。
可行写法
方案1:显式启用bash的extglob特性(完全匹配原命令逻辑)
用三引号包裹多行脚本,显式指定bash解释器并开启extglob,无需额外转义特殊字符:
sh ''' #!/bin/bash shopt -s extglob rm -rv !(_deps) '''
如果需要单行写法,可在调用bash时通过参数直接开启extglob:
sh 'bash -O extglob -c "rm -rv !(_deps)"'
方案2:用find命令实现(无扩展依赖,兼容性更强)
如果不想依赖bash的扩展特性,可以用POSIX标准的find命令实现完全相同的删除效果,兼容所有标准shell:
sh 'find . -maxdepth 1 -not -name "_deps" -not -name "." -exec rm -rv {} +'
参数说明:
-maxdepth 1:仅处理当前目录下的文件/目录,不会递归进入_deps内部-not -name "_deps":排除需要保留的_deps目录-not -name ".":排除当前目录本身,避免误删当前工作目录
原有写法错误说明
sh '''rm -rv !(_deps)''':默认调用/bin/sh执行,未开启extglob,无法识别!()通配语法,抛出括号相关语法错误sh 'rm -rv !\\(_deps\\)':多层转义后括号失去通配语义,shell直接查找名为!(_deps)的普通文件,触发文件不存在报错sh 'rm -rv !\(_deps\)':Groovy单引号字符串不识别\(这类无效转义,直接抛出解析错误sh 'rm -rv !(_deps)':与第一种写法问题一致,默认shell不支持extglob语法,无法解析通配规则
内容的提问来源于stack exchange,提问作者Mariusz Jaskółka
相关产品推荐
相关产品推荐

