Jenkins script块执行多条bash命令报not found及&&不生效问题
Jenkins流水线sh步骤执行多条bash命令报错解决方案
错误原因
你的代码存在3处核心问题:
- 你将后续if判断语句用单引号整体包裹,shell会把整段if字符串当作可执行文件名去查找,直接触发
not found报错;同时你错误使用了单&符号,该符号是后台执行语法,会导致前后两段命令异步执行,无法正确获取前序命令的退出状态。 - 如果你使用
&&连接命令,前序grep命令未匹配到内容时退出码为非0,&&后的命令会被直接跳过,因此不会执行也没有输出。 - Jenkins的sh步骤默认使用
/bin/sh(POSIX标准shell)执行命令,不支持[[ ]]这类bash专属语法,直接使用会导致语法错误。
修复方案
推荐使用Groovy多行三引号编写shell脚本,不需要处理复杂的转义逻辑,可读性更高:
script { unit_test_result = sh ( script: ''' # 捕获过滤后的测试结果行 TEST_CONTENT=$(mvn clean test | grep 'Tests run:' | grep -v 'Time elapsed') # 判断grep是否匹配到结果 if [ $? -ne 0 ]; then echo "No Unit tests to run!" else echo "$TEST_CONTENT" fi ''', returnStdout: true, ).trim() }
如果你需要保留单行写法,修正后代码如下:
script { unit_test_result = sh ( script: 'mvn clean test | grep \'Tests run:\' | grep -v \'Time elapsed\'; if [ $? -ne 0 ]; then echo "No Unit tests to run!"; fi', returnStdout: true, ).trim() }
补充说明
- 末尾添加
trim()是为了移除sh命令返回结果默认携带的末尾换行符,避免后续逻辑处理时出现多余空白字符。 - 如果你需要判断
mvn命令本身是否执行成功(而非仅判断是否有测试结果行),可以指定使用bash执行,通过PIPESTATUS数组获取管道中任意位置命令的退出码:
script: '''#!/bin/bash TEST_CONTENT=$(mvn clean test | grep 'Tests run:' | grep -v 'Time elapsed') # ${PIPESTATUS[0]}对应mvn命令的退出码,${PIPESTATUS[1]}对应第一个grep的退出码,以此类推 if [ ${PIPESTATUS[0]} -ne 0 ]; then echo "Mvn test execution failed!" elif [ $? -ne 0 ]; then echo "No Unit tests to run!" else echo "$TEST_CONTENT" fi '''
内容的提问来源于stack exchange,提问作者user630702
相关产品推荐
相关产品推荐

