jxr*_*mos 1 jenkins jenkins-pipeline
我试图动态定义一个变量,稍后在我的Jenkins管道的一些shell命令中使用它,并抛出异常。我什至尝试将变量从环境部分预定义为无济于事。这是被禁止的操作吗?我的其他变量myVar似乎工作正常,但是在管道中是一个常量。
pipeline {
agent any
environment {
py2Ana=""
myVar="ABCDE"
}
stages {
stage('Stage1') {
steps {
sh """
echo myVar=$myVar
echo Find Anaconda2 Python installation...
py2Ana=`which -a python | grep --max-count=1 anaconda2`
if [[ -z "$py2Ana" ]]; then
echo ERROR: must have a valid Anaconda 2 distribution installed and on the PATH for this job.
exit 1 # terminate and indicate error
fi
"""
}
}
}
Run Code Online (Sandbox Code Playgroud)
groovy.lang.MissingPropertyException: No such property: py2Ana for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:242)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:288)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:268)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:268)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at WorkflowScript.run(WorkflowScript:21)
Run Code Online (Sandbox Code Playgroud)
Joe*_*eAC 13
正如@jxramos 所说,Jenkins 正在尝试解析脚本中的变量。它将任何 $string 解释为需要替换的变量。解决方案是转义脚本内变量的 $ ,如下所示:
pipeline {
agent any
stages {
stage('test stage'){
steps {
sh """#!/bin/bash
myvar=somevalue
echo "The value is \$myvar"
"""
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您愿意的话,Jenkins在预处理步骤中似乎强制执行一个变量替换优先级。换句话说,没有延迟扩展,就像Windows批处理文件中的行为一样setlocal ENABLEDELAYEDEXPANSION。这说明了正在发生的事情,这是我用来确定这一点的测试管道:
pipeline {
agent any
environment {
py2Ana="DEFAULT"
}
stages {
stage('Stage1') {
steps {
sh """
echo py2Ana=$py2Ana
py2Ana=Initialized
echo py2Ana Initialized=$py2Ana
"""
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将产生以下控制台输出...
Started by user unknown or anonymous
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Stage1)
[Pipeline] sh
[TestPipeline] Running shell script
+ echo py2Ana=DEFAULT
py2Ana=DEFAULT
+ py2Ana=Initialized
+ echo py2Ana Initialized=DEFAULT
py2Ana Initialized=DEFAULT
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Run Code Online (Sandbox Code Playgroud)
这样做的另一个限制是,您真的不能sh在Jenkins声明性管道脚本的部分中使用动态变量,因为Jenkins将在执行之前首先尝试解析所有变量。因此,以下内容始终会产生错误
sh """
for filename in /tmp/**; do
echo filename=$filename
done
"""
Run Code Online (Sandbox Code Playgroud)
错误是...
groovy.lang.MissingPropertyException: No such property: filename for class: groovy.lang.Binding
Run Code Online (Sandbox Code Playgroud)
一个人需要动态定义一个脚本(在找到一种方法来逃避$写入文件之后),或者已经在源代码中执行了该脚本。
该错误本身似乎确实是由空字符串的赋值引起的。
但是:您真的需要在 Jenkinsfile 中定义该环境变量吗?对我来说,您似乎只想从 shell 脚本中设置和读取变量。但它的编码方式if [[ -z "$py2Ana" ]]; then永远不会获取 shell 脚本设置的值 - 它总是想要使用 Jenkinsfile 中的属性 - 这是行不通的。
您可以使用if [[ -z "${env.py2Ana}" ]]; thenif 条件来修复该错误,但它仍然不会获取上一行设置的值,但始终读取 Jenkinsfile 中设置的空字符串。
要解决这个问题,您可以将整个字符串用单引号引起来,例如(也许您甚至想去掉 then myVar)...:
pipeline {
agent any
stages {
stage('Stage1') {
steps {
sh '''
echo Find Anaconda2 Python installation...
py2Ana=`which -a python | grep --max-count=1 anaconda2`
if [[ -z "$py2Ana" ]]; then
echo ERROR: must have a valid Anaconda 2 distribution installed and on the PATH for this job.
exit 1 # terminate and indicate error
fi
'''
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
...或者在前面添加一个反斜杠,$py2Ana例如:
pipeline {
agent any
stages {
stage('Stage1') {
steps {
sh """
echo Find Anaconda2 Python installation...
py2Ana=`which -a python | grep --max-count=1 anaconda2`
if [[ -z "\$py2Ana" ]]; then
echo ERROR: must have a valid Anaconda 2 distribution installed and on the PATH for this job.
exit 1 # terminate and indicate error
fi
"""
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
env.py2Ana无论哪种方式,如果没有在代码中引用,我怀疑environmentJenkinsfile 中的块仍然有意义 - 这就是我从示例中删除它的原因。
| 归档时间: |
|
| 查看次数: |
5273 次 |
| 最近记录: |