我试图动态定义一个变量,稍后在我的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
"""
}
}
}
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)
答案 0 :(得分:2)
如果您愿意,Jenkins似乎在预处理步骤中强制执行了变量替换优先级。换句话说,没有延迟扩展,就像在Windows批处理文件中使用setlocal ENABLEDELAYEDEXPANSION
时那样。这说明了发生了什么,这是我用来确定这一点的测试管道:
pipeline {
agent any
environment {
py2Ana="DEFAULT"
}
stages {
stage('Stage1') {
steps {
sh """
echo py2Ana=$py2Ana
py2Ana=Initialized
echo py2Ana Initialized=$py2Ana
"""
}
}
}
}
这将产生以下控制台输出...
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
这带来的另一个限制是,您真的不能在Jenkins声明式管道脚本的sh
部分中使用动态变量,因为Jenkins将在执行之前首先尝试解析所有变量。因此,以下内容始终会产生错误
sh """
for filename in /tmp/**; do
echo filename=$filename
done
"""
错误正在...
groovy.lang.MissingPropertyException: No such property: filename for class: groovy.lang.Binding
一个人需要动态定义一个脚本(在找出一种逃避$
写入文件的方法之后),或者已经在源代码中将其执行。
答案 1 :(得分:1)
正如@jxramos所说,Jenkins试图解析脚本中的变量。它将任何$ string解释为需要替换的变量。 解决方法是转义脚本变量中的$,如下所示:
pipeline {
agent any
stages {
stage('test stage'){
steps {
sh """
#!/bin/bash
myvar=somevalue
echo "The value is \$myvar"
"""
}
}
}
}
答案 2 :(得分:0)
变量之前必须带有 def
pipeline {
agent none
stages {
stage("build") {
def foo = "foo";
}
}
}
在我的情况下,我在阶段{}之前初始化了我的vars
def var = "var
stages {
stage("build") {
def foo = "foo";
}
}
答案 3 :(得分:0)
只需将一个值添加到py2Ana
environment {
py2Ana="1234"
myVar="ABCDE"
}
如果传递空字符串,则不会在环境中创建变量:)
答案 4 :(得分:0)
错误本身似乎真的是由分配空字符串引起的。
但是:您真的需要在Jenkinsfile中定义该环境变量吗?
在我看来,您似乎只想在Shell脚本中设置和读取变量。但是,它对if [[ -z "$py2Ana" ]]; then
进行编码的方式永远不会采用shell脚本设置的值-它总是想使用Jenkinsfile中的属性-无效。
您可以将if [[ -z "${env.py2Ana}" ]]; then
用于if条件,该条件可以解决该错误,但仍无法获取上一行所设置的值,但始终读取Jenkinsfile中设置的空字符串。
要解决此问题,您可以将整个字符串用单引号引起来,例如(也许您甚至想摆脱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
'''
}
}
}
}
...或在$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
"""
}
}
}
}
无论哪种方式都无需在代码中引用env.py2Ana
,我怀疑Jenkinsfile中的environment
块是否仍然有意义-这就是为什么我从示例中将其删除了。