groovy脚本sh执行注意单双引号问题

发布时间 2023-07-14 13:44:42作者: 豆浆D

正常groovy脚本

#!/usr/bin/env groovy

    pipeline {
    //确认使用主机/节点机
    agent  { 
        node { label 'master'} 
    }
    options {
        parallelsAlwaysFailFast()
    }
    //  声明参数 
    parameters{
        //  传包名称
        string(name:'appname', defaultValue: 'search-ng', description: '名称')
        // IP
        string(name:'ip', defaultValue: '10.60.175.63', description: 'IP')
        //git代码路径
        string(name:'repoUrl', defaultValue: 'http://10.70.14.156/issts/search-ng.git', description: 'git代码路径')
        // 编译打包
        string(name:'build', defaultValue: 'mvn -f pom.xml clean package -U -Dmaven.test.skip=true -Dexec.skip=true -P test', description: '编译打包命令')
        // tomcat目录
        string(name:'tomcatHome', defaultValue: '/apps/admin/taobao-tomcat-production-7.0.59.3', description: 'tomcat家目录')
        // 指定分支
        string(name:'branch', defaultValue: 'test', description: 'git分支')
        // 用户
        string(name:'user', defaultValue: 'tomcat', description: 'server用户')
        // classfiles
        string(name:'classfiles', defaultValue: 'target/classes', description: '类文件')
        // sourcefiles
        string(name:'sourcefiles', defaultValue: 'src/main/java', description: '源文件')
    }

    environment{
        // git凭证
        CRED_ID='view'
        // maven 路径
        MAVEN_DIR='/opt/apache-maven-3.8.6/bin'
        // sonar server地址
        SONAR_IP='SONAR_IP'
        // sonar-scanner
        SONAR_SCANNER='/opt/sonar-scanner/bin'
        // sonar数据
        SONAR_DATA='/var/jenkins_home/sonarData' 
        //java libraries
        LIB_HOME='/root/.m2/repository/**/*.jar'
        
    }

    stages {
        // 拉取代码
        stage('Checkout') {
            steps {
                script {
                //从git拉取代码
                def scmVars = checkout([
                    $class: 'GitSCM',
                    branches: [
                      [
                        name: "${params.branch}"
                      ]
                    ],
                    doGenerateSubmoduleConfigurations: false,
                    extensions: [
                      [
                        $class: 'SubmoduleOption',
                        disableSubmodules: false,
                        parentCredentials: true,
                        recursiveSubmodules: true,
                        reference: '',
                        trackingSubmodules: false
                      ]
                    ],
                    submoduleCfg: [],
                    userRemoteConfigs: [
                      [
                        credentialsId: CRED_ID,
                        url: "${params.repoUrl}"
                      ]
                    ]
                  ]
                )
                 gitversion = scmVars.GIT_COMMIT
                }
                 sh "echo ${gitversion}"
            }
        }

        // 编译
        stage('build') {
            steps{
                // maven构建
                sh "${MAVEN_DIR}/${params.build}"
            }
        }


        //  添加sonar配置
        stage('restart') {
            steps{ 
                echo '添加sonar配置'
               // sh "ssh ${params.user}@${params.ip} 'echo JAVA_OPTS="$JAVA_OPTS -javaagent:${JACOCO_HOME}/lib/jacocoagent.jar=includes=*,output=tcpserver,port=8893,address=$(params.ip)" >> ${params.tomcatHome}/bin/catalina.sh'" 
                echo 'sonar配置完成'

            }
        }

        //  生成sonar报告
        stage('sonar') {
            steps{
                // 判断是否删除result
                script {
                    if (params.is_delete_result == 'yes') {
                        echo '删除result'
                        sh 'rm -rf ${SONAR_DATA}/${params.appname}/result.exec'
                        sh 'rm -rf ${SONAR_DATA}/${params.appname}/result.xml"'
                    } else {
                        echo '不删除result'
                    }
                }
                echo '生成sonar报告'
                sh "mkdir ${SONAR_DATA}/${params.appname} -p"
                sh "java -jar /opt/jacococli.jar dump --address ${params.ip} --port 8893 --destfile ${SONAR_DATA}/${params.appname}/result.exec"
                sh "java -jar /opt/jacococli.jar report ${SONAR_DATA}/${params.appname}/result.exec --classfiles ${params.classfiles} --sourcefiles ${params.sourcefiles} --xml ${SONAR_DATA}/${params.appname}/result.xml"
                sh "${SONAR_SCANNER}/sonar-scanner -D'sonar.branch.name=test' -D'sonar.java.source=1.8' -D'sonar.coverage.jacoco.xmlReportPaths=${SONAR_DATA}/${params.appname}/result.xml' -D'sonar.projectKey=${params.appname}' -D'sonar.sources=${params.sourcefiles}'  -D'sonar.java.binaries=${params.classfiles}'  -D'sonar.scm.provider=git' -D'maven.test.skip=true' -D'sonar.java.libraries=${LIB_HOME}'"

            }
        }


    }
}

正常groovy流水线脚本,看上去没啥问题,却偏偏报错了:

[Pipeline] sh
/var/jenkins_home/workspace/stg-search-ng@tmp/durable-0aa4ef96/script.sh: line 1: ${SONAR_DATA}/${params.appname}/result.exec: bad substitution

 

很容易看出${SONAR_DATA}/${params.appname}/result.exec这个变量没有识别到

排查一圈下来,原来是单双引号的问题改成下面就好了

// ... 省略了一些代码 ...

stage('sonar') {
    steps{
        // 判断是否删除result
        script {
            if (params.is_delete_result == 'yes') {
                echo '删除result'
                sh "rm -rf ${SONAR_DATA}/${params.appname}/result.exec"
                sh "rm -rf ${SONAR_DATA}/${params.appname}/result.xml"
            } else {
                echo '不删除result'
            }
        }
        echo '生成sonar报告'
        sh "mkdir ${SONAR_DATA}/${params.appname} -p"
        sh "java -jar /opt/jacococli.jar dump --address ${params.ip} --port 8893 --destfile ${SONAR_DATA}/${params.appname}/result.exec"
        sh "java -jar /opt/jacococli.jar report ${SONAR_DATA}/${params.appname}/result.exec --classfiles ${params.classfiles} --sourcefiles ${params.sourcefiles} --xml ${SONAR_DATA}/${params.appname}/result.xml"
        sh "${SONAR_SCANNER}/sonar-scanner -D'sonar.branch.name=test' -D'sonar.java.source=1.8' -D'sonar.coverage.jacoco.xmlReportPaths=${SONAR_DATA}/${params.appname}/result.xml' -D'sonar.projectKey=${params.appname}' -D'sonar.sources=${params.sourcefiles}'  -D'sonar.java.binaries=${params.classfiles}'  -D'sonar.scm.provider=git' -D'maven.test.skip=true' -D'sonar.java.libraries=${LIB_HOME}'"
    }
}

注意sh执行脚本要用双引号