Jenkins声明式Pipeline调用Bash脚本无法接收传参的解决方法
问题根因
这个问题和Bash本身的参数传递逻辑无关,完全是Jenkins Pipeline的Groovy字符串解析机制导致的:
- Groovy语法中,三双引号
"""包裹的多行字符串默认开启变量插值,所有$开头的标识符都会被Groovy优先解析为当前上下文的Groovy变量,不存在对应变量时会直接替换为空字符串。你写在sh步骤里的Bash位置变量$0、$@、$1全部在Groovy解析阶段被替换成了空值,最终传给Bash执行的脚本里,参数取值逻辑已经被破坏,自然表现为接收到的参数为空。 - 直接在终端执行命令、或者通过独立的第三方脚本调用时,不会经过Groovy的字符串解析流程,所以参数传递完全正常。
- 补充说明:你写在sh步骤内容第一行的
#!/bin/bash没有实际作用,Jenkins的sh步骤会默认将传入的内容通过系统shell的-c参数执行,shebang行在这里只会被识别为普通注释,不影响执行逻辑。
修复方案
两种方案都可以解决问题,优先选第一种,维护成本最低。
方案1:用三单引号包裹sh脚本(推荐)
Groovy中三单引号'''包裹的字符串是纯字面量,不会做任何变量插值,所有内容会原样传递给Bash执行,和你在终端直接写脚本的行为完全一致,不需要逐个转义特殊字符。修改后的Jenkinsfile示例:
pipeline { agent { label "ubuntu" } options { timeout(time: 1, unit: 'HOURS') } stages { stage('Build') { steps { sh ''' # 原有其他业务逻辑 . ./Scripts/install_tools.sh "force" ''' } } } }
如果需要在脚本中使用Groovy侧定义的动态参数,不要直接在字符串里插值,优先通过environment块把参数注入为环境变量,Bash侧可以直接读取,避免转义问题:
pipeline { agent { label "ubuntu" } environment { INSTALL_MODE = "force" } stages { stage('Build') { steps { sh ''' . ./Scripts/install_tools.sh "$INSTALL_MODE" ''' } } } }
方案2:转义双引号字符串中所有Bash侧的$符号
如果你必须使用三双引号包裹脚本(比如只需要插入极少量Groovy变量),给所有Bash侧使用的$符号前加反斜杠\转义,告诉Groovy不要解析这些标识,原样传递给Bash即可。示例:
pipeline { agent { label "ubuntu" } options { timeout(time: 1, unit: 'HOURS') } stages { stage('Build') { steps { sh """ # 注意所有Bash变量的$前都加了反斜杠 echo "Running script: \$0" echo "Received args: \$@" . ./Scripts/install_tools.sh "force" """ } } } }
这种方式需要手动转义每一个Bash变量引用,漏转义就会复现参数为空的问题,仅适合脚本逻辑非常简单的场景。
额外说明
你当前使用.(source命令)加载install_tools.sh的语法本身是正确的,Bash的source原生支持向被加载脚本传递位置参数,不需要修改为直接执行脚本的方式,只要修复Groovy插值的问题,参数就能正常传递。
内容的提问来源于stack exchange,提问作者Morkkis
相关产品推荐
相关产品推荐

