可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
A step in my pipeline uploads a .tar to an artifactory server. I am getting a Bad substitution error when passing in env.BUILD_NUMBER, but the same commands works when the number is hard coded. The script is written in groovy through jenkins and is running in the jenkins workspace.
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"'
returns the errors:
[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
If hard code in a build number and swap out ${env.BUILD_NUMBER}
I get no errors and the code runs successfully.
sh 'curl -v --user user:password --data-binary ${buildDir}package113.tar -X PUT "http://artifactory.mydomain.com/artifactory/release-packages/package113.tar"'
I use ${env.BUILD_NUMBER} within other sh commands within the same script and have no issues in any other places.
回答1:
This turned out to be a syntax issue. Wrapping the command in '
's caused ${env.BUILD_NUMBER
to be passed instead of its value. I wrapped the whole command in "
s and escaped the nested. Works fine now.
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\""
回答2:
Usually the most common issue for:
Bad substitution
error is to use sh
instead of bash
.
Especially when using Jenkins, if you're using Execute shell, make sure your Command starts with shebang, e.g. #!/bin/bash -xe
or #!/usr/bin/env bash
.
回答3:
Actually, you seem to have misunderstood the env
variable. In your sh
block, you should access ${BUILD_NUMBER}
directly.
Reason/Explanation: env
represents the environment inside the script. This environment is used/available directly to anything that is executed, e.g. shell scripts.
Please also pay attention to not write anything to env.*
, but use withEnv{}
blocks instead.
回答4:
I can definitely tell you, it's all about sh shell and bash shell. I fixed this problem by specifying #!/bin/bash -xe
as follows:
node { stage("Preparing"){ sh'''#!/bin/bash -xe colls=( col1 col2 col3 ) for eachCol in ${colls[@]} do echo $eachCol done ''' } }
回答5:
I was having the issue with showing the {env.MAJOR_VERSION}
in an artifactory of jar file . show I approaches by keeping of environment step in 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 } } }
I got the issue solved and then it was not showing me bad substitution in my Jenkins build output. so environment step plays a more role in Jenkinsfile.