groovy Jenkins:管道sh错误替换错误

bwitn5fc  于 2022-11-28  发布在  Jenkins
关注(0)|答案(9)|浏览(288)

我的管道中的一个步骤将一个.tar文件上传到一个artifactory服务器。当传入env.BUILD_NUMBER时,我得到了一个Bad替换错误,但是当数字是硬编码时,同样的命令也能工作。该脚本是通过jenkins用groovy编写的,并且在jenkins工作区中运行。

sh 'curl -v --user user:password --data-binary ${buildDir}package${env.BUILD_NUMBER}.tar -X PUT "http://artifactory.mydomain.com/artifactory/release-packages/package${env.BUILD_NUMBER}.tar"'

返回错误:

[Pipeline] sh
[Package_Deploy_Pipeline] Running shell script
/var/lib/jenkins/workspace/Package_Deploy_Pipeline@tmp/durable-4c8b7958/script.sh: 2: 
/var/lib/jenkins/workspace/Package_Deploy_Pipeline@tmp/durable-4c8b7958/script.sh: Bad substitution
[Pipeline] } //node
[Pipeline] Allocate node : End
[Pipeline] End of Pipeline
ERROR: script returned exit code 2

如果硬编码在一个构建号和交换出${env.BUILD_NUMBER}我得到没有错误和代码运行成功。

sh 'curl -v --user user:password --data-binary ${buildDir}package113.tar -X PUT "http://artifactory.mydomain.com/artifactory/release-packages/package113.tar"'

我在同一脚本的其他sh命令中使用了${env.BUILD_NUMBER},在其他任何地方都没有问题。

3pmvbmvn

3pmvbmvn1#

结果发现这是一个语法问题。将命令 Package 在'中导致传递的是${env.BUILD_NUMBER而不是它的值。我将整个命令 Package 在"中并转义了嵌套。现在工作正常。

sh "curl -v --user user:password --data-binary ${buildDir}package${env.BUILD_NUMBER}.tar -X PUT \"http://artifactory.mydomain.com/artifactory/release-packages/package${env.BUILD_NUMBER}.tar\""
vngu2lb8

vngu2lb82#

为了将groovy参数传递到Jenkins管道中的bash脚本中(有时会导致错误的替换)您有两个选项

三重双引号方式[“““]OR三重单引号方式[ '' ]

1.在三重双引号中您可以使用${someVariable}呈现groovy中的normal参数,如果它是环境变量${env.someVariable},如果它是注入到作业${params.someVariable}中的参数

示例

def YOUR_APPLICATION_PATH= "${WORKSPACE}/myApp/"

      sh """#!/bin/bash
      cd ${YOUR_APPLICATION_PATH}
      npm install
      """

1.在三个单引号中事情变得有点棘手,您 * 可以将参数传递给环境参数 * 并通过"\${someVaraiable}" * 使用它,或者使用 * ''' + someVaraiable + '''连接groovy参数

示例

def YOUR_APPLICATION_PATH= "${WORKSPACE}/myApp/"

   sh '''#!/bin/bash
          cd ''' + YOUR_APPLICATION_PATH + '''
          npm install
    '''

pipeline{
     agent { node { label "test" } }
     environment {
       YOUR_APPLICATION_PATH = "${WORKSPACE}/myapp/"
     }

     continue...
     continue...
     continue...

     sh '''#!/bin/bash
          cd "\${YOUR_APPLICATION_PATH}"
          npm install
    '''

    //OR
    sh '''#!/bin/bash
          cd "\${env.YOUR_APPLICATION_PATH}"
          npm install
    '''
jei2mxaa

jei2mxaa3#

实际上,您似乎误解了env变量。在您的sh块中,您应该直接访问${BUILD_NUMBER}

原因/说明:env表示脚本内的环境。此环境可直接用于/可用于执行的任何内容,例如shell脚本。

请注意,不要向env.*写入任何内容,而是使用withEnv{}块。

dnph8jn4

dnph8jn44#

通常最常见的问题为:
替换错误
错误是使用sh而不是bash
特别是在使用Jenkins时,如果您使用的是 * Execute shell *,请确保您的 * Command * 以 * shebang * 开头,例如#!/bin/bash -xe#!/usr/bin/env bash

des4xlb0

des4xlb05#

我可以明确地告诉你,这都是关于sh shell和bash shell的。我通过如下指定#!/bin/bash -xe来修复这个问题:

node {
    stage("Preparing"){
        sh'''#!/bin/bash -xe
            colls=( col1 col2 col3 )
            for eachCol in ${colls[@]}
            do
              echo $eachCol
            done
        '''
    }      
}
axkjgtzd

axkjgtzd6#

我在JenkinsPipeline上为Amazon S3应用程序上传工作时遇到了同样的问题。
我的剧本是这样的:

pipeline {  
  agent any
  parameters {
    string(name: 'Bucket', defaultValue: 's3-pipeline-test', description: 'The name of the Amazon S3 Bucket')
    string(name: 'Prefix', defaultValue: 'my-website', description: 'Application directory in the Amazon S3 Bucket')
    string(name: 'Build', defaultValue: 'public/', description: 'Build directory for the application')
  }  
  stages {  
    stage('Build') {  
      steps {
        echo 'Running build phase'
        sh 'npm install' // Install packages
        sh 'npm run build' // Build project 
        sh 'ls' // List project files
      }  
    }  
    stage('Deploy') {  
      steps {  
        echo 'Running deploy phase'
        withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWSCredentials', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) { 
          sh 'aws s3 ls' // List AWS S3 buckets
          sh 'aws s3 sync "${params.Build}" s3://"${params.Bucket}/${params.Prefix}" --delete' // Sync project files with AWS S3 Bucket project path
        }  
      }   
    }
  }
  post { 
    success {  
      echo 'Deployment to Amazon S3 suceeded'  
    }  
    failure {  
      echo 'Deployment to Amazon S3 failed'  
    }  
  }  
}
    • 以下是我的修正方法**:

由于这是对变量的插值调用,我不得不在脚本的这一行中替换单引号(''):

sh 'aws s3 sync "${params.Build}" s3://"${params.Bucket}/${params.Prefix}" --delete' // Sync project files with AWS S3 Bucket project path

双引号(""):

sh "aws s3 sync ${params.Build} s3://${params.Bucket}/${params.Prefix} --delete" // Sync project files with AWS S3 Bucket project path

所以我的剧本后来看起来是这样的:

pipeline {  
  agent any
  parameters {
    string(name: 'Bucket', defaultValue: 's3-pipeline-test', description: 'The name of the Amazon S3 Bucket')
    string(name: 'Prefix', defaultValue: 'my-website', description: 'Application directory in the Amazon S3 Bucket')
    string(name: 'Build', defaultValue: 'public/', description: 'Build directory for the application')
  }  
  stages {  
    stage('Build') {  
      steps {
        echo 'Running build phase'
        sh 'npm install' // Install packages
        sh 'npm run build' // Build project 
        sh 'ls' // List project files
      }  
    }  
    stage('Deploy') {  
      steps {  
        echo 'Running deploy phase'
        withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWSCredentials', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) { 
          sh 'aws s3 ls' // List AWS S3 buckets
          sh "aws s3 sync ${params.Build} s3://${params.Bucket}/${params.Prefix} --delete" // Sync project files with AWS S3 Bucket project path
        }  
      }   
    }
  }
  post { 
    success {  
      echo 'Deployment to Amazon S3 suceeded'  
    }  
    failure {  
      echo 'Deployment to Amazon S3 failed'  
    }  
  }  
}

就这样了
"我希望这能帮上忙"

wfveoks0

wfveoks07#

我在jar文件的一个工件中显示{env.MAJOR_VERSION}时遇到了问题。通过在Jenkinsfile中保持环境步骤来显示我的方法。

pipeline {
agent any
environment {
MAJOR_VERSION = 1
}

stages {
stage('build') {
  steps {
      sh 'ant -f build.xml -v'
 }
}
}
post {
 always{
   archiveArtifacts artifacts: 'dist/*.jar', fingerprint: true
 }
}
}

我解决了这个问题,然后它没有在我的Jenkins构建输出中显示坏的替换。所以环境步骤在Jenkinsfile中扮演了更多的角色。

ktecyv1j

ktecyv1j8#

@avivamg的建议对我不起作用,下面是对我起作用的语法:

sh "python3 ${env.WORKSPACE}/package.py --product productname " +
    "--build_dir ${release_build_dir} " +
    "--signed_product_dir ${signed_product_dir} " +
    "--version ${build_version}"
mcvgt66p

mcvgt66p9#

Jenkins脚本在“sh”命令行中失败,例如:

sh 'npm run build' <-- Fails referring to package.json

需要更改为:

sh 'npm run ng build....'

... ng $PATH未被package.json找到。

相关问题