如何将Jenkinsfile中带空格的变量正确传递给shell命令
问题根因
Jenkins Pipeline的sh步骤存在默认的字符串拆分转义逻辑:当传入的命令字符串中存在未被显式包裹为整体的空格时,Jenkins会自动按空格拆分命令片段,给每个片段单独包裹单引号后传给shell执行。你之前的写法踩了三个核心问题:
- 用单引号定义
script参数时,Groovy不会提前完成变量插值,Jenkins拿到拆分后的字符串片段才做变量替换,直接把带空格的时间值拆成了两个独立参数 - 转义引号只包裹了变量值的部分边界,没有把整个
time=xxx参数包裹为不可拆分的整体 - 变量名不统一,定义的变量是
MYTIME,脚本里引用的是$TIME,容易出现取值异常
可行解法
方案1:双引号定义脚本+整体包裹参数(最简便)
把script参数的外层引号换成双引号让Groovy提前完成变量插值,同时把整个-e对应的参数整体用单引号包裹,彻底阻断Jenkins的自动空格拆分,配置如下:
stage('list') { steps{ sh script: "ansible-playbook -i ./hosts.ini ./ping_playbook.yml -e 'time=\"${MYTIME}\"' --limit ${ENV}", label: "ping test" } }
该写法最终传给shell的命令为:
ansible-playbook -i ./hosts.ini ./ping_playbook.yml -e 'time="2022-01-02 03:04:05"' --limit sdktest
shell会把单引号内的内容识别为一个完整参数,ansible最终接收到的time变量值就是带空格的完整时间字符串,完全符合预期。
方案2:环境变量注入(零转义冲突,最稳妥)
如果后续要传的带空格变量更多,不想处理Groovy和shell两层转义的嵌套问题,可以通过sh步骤自带的environment参数把变量直接注入shell执行上下文,完全绕开Groovy插值的转义逻辑:
stage('list') { steps{ sh( script: 'ansible-playbook -i ./hosts.ini ./ping_playbook.yml -e "time=\\"$MYTIME\\"" --limit "$ENV"', label: "ping test", environment: [ MYTIME: MYTIME, ENV: ENV ] ) } }
这种写法下所有变量替换都在shell层完成,不会触发Jenkins的自动参数拆分,适合复杂参数传递场景。
避坑提醒
- 不要在单引号包裹的
script字符串内直接写$变量名,Groovy不会解析单引号字符串内的插值占位符,很容易触发Jenkins的自动拆分逻辑 - 不要只给变量值加转义引号,必须把整个键值对参数作为整体包裹,否则空格依然会被识别为参数分隔符
- 引用变量前确认名称和定义时完全一致,避免取空值导致命令执行异常
内容的提问来源于stack exchange,提问作者conandor
相关产品推荐
相关产品推荐

