Jenkins pipeline执行sh命令报set Illegal option -o pipefail如何定位原因
错误定位步骤与修复方案
定位流程
- 首先确认Jenkins运行节点的
/bin/sh指向的实际shell:执行命令ls -l /bin/sh,Debian/Ubuntu等Debian系系统默认会将/bin/sh软链接到轻量化的dash,而非bash,dash原生不支持pipefail选项,是该报错的最高发诱因。 - 验证不同shell对
pipefail的支持性:分别执行以下两条命令测试
若第一条执行报错、第二条无输出,即可确认是默认sh不支持该选项导致的问题。/bin/sh -c "set -o pipefail" /bin/bash -c "set -o pipefail" - 确认报错所属的脚本:你的场景中报错指向
base/script.sh的第1行,需额外检查该脚本的首行shebang配置,若写的是#!/bin/sh,该脚本执行时也会调用默认sh,即便外层命令用了bash也会触发报错。 - 确认Jenkins sh步骤的默认执行逻辑:Jenkins的sh步骤默认调用
/bin/sh执行传入的脚本内容,不会使用当前用户手动配置的默认shell,因此手动登录节点执行命令正常不代表Jenkins调用时也能正常执行。
修复方案
- 方案一(最推荐,无系统侧侵入修改):显式指定使用bash执行脚本
- 针对Jenkins sh步骤的命令,两种写法可选:
写法1:脚本开头指定shebang
写法2:通过shell参数指定解释器sh '''#!/bin/bash set -o pipefail && pwd && cd base/path && suite=${features} '''sh shell: '/bin/bash', script: "set -o pipefail && pwd && cd base/path && suite=${features}"- 针对
base/script.sh,将首行shebang修改为#!/bin/bash,或者调用该脚本时显式用bash执行:bash base/script.sh。
- 针对Jenkins sh步骤的命令,两种写法可选:
- 方案二:适配当前默认sh特性:如果必须使用系统默认sh执行,删除所有脚本里的
set -o pipefail配置即可,缺点是管道命令的错误返回码会丢失,不适合需要严格校验执行结果的场景。 - 方案三:修改系统默认sh指向:Debian/Ubuntu系统执行
sudo dpkg-reconfigure dash,选择「否」即可将/bin/sh默认指向bash,该修改会影响整个系统的sh调用,需要评估业务影响后操作。
内容的提问来源于stack exchange,提问作者rohini dingankar
相关产品推荐
相关产品推荐

