Jenkins: 管道 sh 错误替换错误

我管道中的一个步骤上传了一个。一个人工服务器的 tar。当传入 env.BUILD _ NUMBER 时,我得到了一个糟糕的替换错误,但是当数字被硬编码时,同样的命令可以工作。该脚本是通过 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 } ,在其他任何地方都没有问题。

108640 次浏览

这是一个语法问题。将命令包装在 '中会导致传递 ${env.BUILD_NUMBER而不是它的值。我用 "包装了整个命令,并逃离了嵌套。现在没问题了。

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\""

通常最常见的问题是:

替换不当

错误是使用 sh而不是 bash

特别是在使用詹金斯时,如果你使用的是 执行 shell,确保你的 命令翻译: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校开头,例如 #!/bin/bash -xe#!/usr/bin/env bash

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

原因/解释: env表示脚本内部的环境。这个环境可以直接用于执行的任何东西,例如 shell 脚本。

也请注意不要写任何东西到 env.*,而是使用 withEnv{}块代替。

我可以肯定地告诉你,这都是关于 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
'''
}
}

我在一个 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 扮演着更重要的角色。

为了 在 Jenkins 管道中将 Groovy 参数传递到 bash 脚本中(有时造成不好的替换) 你有两个选择:

< strong > 三重双引号方式[“””] 或者 < strong > 三重单引号方式[’’’]

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

例子 :

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


sh """#!/bin/bash
cd ${YOUR_APPLICATION_PATH}
npm install
"""
  1. 在三重单引号 事情变得有点棘手,你 可以将参数传递给环境参数和使用它的 "\${someVaraiable}" 或者使用 ''' + someVaraiable + '''

例子 :

   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
'''

我在为 亚马逊 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'
}
}
}

仅此而已

希望这个能帮上忙

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

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

需要改为:

sh 'npm run ng build....'

... ng $PATH 没有找到的包。 json。

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

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