我正在考虑将 Jenkins 非管道作业移植到管道。 我遇到过这样的情况,如果参数值引用环境变量,例如“${HOME}/etc”,那么参数值将被评估(eval'd),然后作为评估后值传递到我的 shell 脚本步骤“/var/lib/jenkins/etc”。
首先,我没想到这种评估会发生在非管道作业中,并且找不到应该发生这种情况的文档。 这有记录在某处吗?
其次,鉴于这种情况确实发生,我如何在使用 sh() 命令运行 shell 脚本的管道版本中复制该行为? Pipeline 版本获取参数 avar2,值为 ${HOME}/etc。 在管道作业中运行 shell 脚本之前,我还没有找到可以为我完成评估的选项。 看来我必须编写脚本文件来对可能需要它的任何环境变量进行评估。
在管道作业中,我尝试在作业中立即指定 shell 脚本,以及在工作区的文件中指定 shell 脚本。 我在这里只演示第一种情况,即在作业中立即指定 shell 脚本。
我创建了一个带有两个字符串参数的自由式作业:
Name: avar1
Default Value: avar1val
Name: avar2
Default Value: ${HOME}/etc
以及具有文本的“执行 shell”构建步骤:
#!/bin/bash -e
env | sort
运行此作业会提供如下所示的作业控制台文本:
Started by user X
Running as SYSTEM
Building on the built-in node in workspace /var/lib/jenkins/workspace/jam
[jam] $ /bin/bash -e /tmp/jenkins15623yadayada.sh
avar1=avar1val
avar2=/var/lib/jenkins/etc
.
.
.
Finished: SUCCESS
然后我创建了一个管道作业,使用 sh 命令调用相同的 shell 脚本。 它的定义是:
使用两个字符串参数创建管道作业:
Name: avar1
Default Value: avar1val
Name: avar2
Default Value: ${HOME}/etc
以及管道定义“管道脚本”
pipeline {
agent any
stages {
stage('Hello') {
steps {
sh '''#!/bin/bash -e
env | sort
'''
}
}
}
}
运行此作业会在 Jenkins 作业控制台输出中包含此文本
.
.
avar1=avar1val
avar2=${HOME}/etc
.
.
Finished: SUCCESS
这是在 java 11 上的 linux jenkins v2.452.3 上
“为什么”部分很容易解释。自由式作业在一台机器上运行,因此 ${HOME}
可以毫无歧义地扩展。如果它应该扩展,那是一个设计选择,在你提出问题之前,我不知道它已经扩展了。管道作业可以在多台计算机上运行,甚至可以在没有分配代理的情况下运行,因此根据分配的代理(如果有),参数在管道的不同部分可能具有不同的值。
sh "echo ${params.avar2}"
但我建议不要这样做。双展开很难推理。