bash 詹金斯管道 sh 坏替代
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37219348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jenkins Pipeline sh bad substitution
提问by Stephen Nichols
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.
我的管道中的一个步骤将 .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"'
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.
如果在内部版本号中进行硬编码并换出,则${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"'
I use ${env.BUILD_NUMBER} within other sh commands within the same script and have no issues in any other places.
我在同一个脚本中的其他 sh 命令中使用 ${env.BUILD_NUMBER} 并且在任何其他地方都没有问题。
回答by Stephen Nichols
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.
结果证明这是一个语法问题。将命令包装在'
's 中导致${env.BUILD_NUMBER
传递而不是它的值。我将整个命令包装在"
s 中并逃脱了嵌套。现在工作正常。
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\""
回答by patric.schenke
Actually, you seem to have misunderstood the env
variable. In your sh
block, you should access ${BUILD_NUMBER}
directly.
实际上,您似乎误解了env
变量。在您的sh
区块中,您应该${BUILD_NUMBER}
直接访问。
Reason/Explanation:env
represents the environment inside the script. This environment is used/available directly to anything that is executed, e.g. shell scripts.
原因/说明:env
代表脚本内部的环境。此环境可直接用于/可用于执行的任何内容,例如 shell 脚本。
Please also pay attention to not write anything to env.*
, but use withEnv{}
blocks instead.
还请注意不要向 写入任何内容env.*
,而是使用withEnv{}
块。
回答by kenorb
Usually the most common issue for:
通常最常见的问题是:
Bad substitution
坏替代
error is to use sh
instead of bash
.
错误是使用sh
而不是bash
.
Especially when using Jenkins, if you're using Execute shell, make sure your Commandstarts with shebang, e.g. #!/bin/bash -xe
or #!/usr/bin/env bash
.
特别是在使用 Jenkins 时,如果您使用的是Execute shell,请确保您的命令以shebang开头,例如#!/bin/bash -xe
或#!/usr/bin/env bash
。
回答by Gary Gan
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:
我可以肯定地告诉你,这完全是关于 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
'''
}
}
回答by avivamg
In order to Pass groovy parameters into bash scripts in Jenkins pipelines(causing sometimes bad substitions) You got 2 options:
为了将groovy 参数传递到 Jenkins 管道中的 bash 脚本中(有时会导致错误的替换),您有 2 个选项:
The triple double quotes way [ " " " ]OR the triple single quotes way [ ' ' ' ]
该三重双引号的方式[“”“]或三联单引号的方法[‘’']
- In triple double quotesyou can render the normal parameter from groovy using
${someVariable}
,if it's environment variable${env.someVariable}
, if it's parameters injected into your job${params.someVariable}
- 在三重双引号中,您可以使用 groovy 渲染普通参数
${someVariable}
,如果它是环境变量${env.someVariable}
,如果它是注入到您的工作中的参数${params.someVariable}
example:
例子:
def YOUR_APPLICATION_PATH= "${WORKSPACE}/myApp/"
sh """#!/bin/bash
cd ${YOUR_APPLICATION_PATH}
npm install
"""
- In triple single quotesthings getting little bit tricky, you can pass the parameter to environment parameterand using it by
"\${someVaraiable}"
or concating the groovy parameter using''' + someVaraiable + '''
- 在三重单引号中,事情变得有点棘手,您可以将参数传递给环境参数并通过使用它或使用它
"\${someVaraiable}"
连接 groovy 参数''' + someVaraiable + '''
examples:
例子:
def YOUR_APPLICATION_PATH= "${WORKSPACE}/myApp/"
sh '''#!/bin/bash
cd ''' + YOUR_APPLICATION_PATH + '''
npm install
'''
OR
或者
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
'''
回答by Aamir M Meman
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.
我在显示{env.MAJOR_VERSION}
jar 文件的人工制品时遇到了问题。通过在 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.
我解决了这个问题,然后在我的 Jenkins 构建输出中没有显示出错误的替代。所以环境步骤在 Jenkinsfile 中扮演着更多的角色。