10分钟搞定让你困惑的 Jenkins 环境变量
前言
Jenkins, DevOps 技术栈的核心之一,CI/CD 离不开编写 Pipeline 脚本,上手 Jenkins ,简单查一下文档,你就应该不会被 agent,stages,step 这类关键词弄懵,也能很快构建出 pipeline 的骨架
但是当向骨架中填充内容的时候,尤其如何利用环境变量(系统内置 | 自定义),多数人都会变得比较混乱,浪费很多时间,本文就帮助大家快速通关环境变量

准备
如果你想一边阅读本文,一边实践,但是没有 Jenkins 服务可用,又想快速尝试,可以应用 Docker 一个命令快速搭建 Jenkins 服务
docker container run --rm -p 8080:8080 -p 50000:50000 --name=jenkins -v $(pwd):/var/jenkins_home jenkins/jenkins

2021 年了,本地没有 Docker 说不过去了,过来瞧瞧 Docker 系列是否入得了你的法眼?
打开浏览器输入:localhost:8080
- 找到终端的临时密码登陆
- 安装推荐的依赖
- 创建新的 Pipeline 类型的 Item
- 点击左侧 Config,然后在页面底部 Pipeline 部分输入我们接下来写的脚本进行测试就好了

就是这么简单.....
认识 Jenkins 环境变量
Jenkins 环境变量就是通过
env关键字暴露出来的全局变量,可以在 Jenkins 文件的任何位置使用
其实和你使用的编程语言中的全局变量没有实质差别
查看 Jenkins 系统内置环境变量
Jenkins 在系统内置了很多环境变量方便我们快速使用,查看起来有两种方式:
方式一:
直接在浏览器中访问 ${YOUR_JENKINS_HOST}/env-vars.html 页面就可以,比如 http://localhost:8080/env-vars.html ,每个变量的用途写的都很清楚

方式二
通过执行 printenv shell 命令来获取:
pipeline {
agent any
stages {
stage("Env Variables") {
steps {
sh "printenv"
}
}
}
}
直接 Save - Build, 在终端 log 中你会看到相应的环境变量,并且可以快速看到他们当前的值

通常这两种方式可以结合使用
读取环境变量
上面我们说了 env 是环境变量的关键字,但是读取 Jenkins 内置的这些环境变量,env 关键字是可有可无, 但不能没了底裤,都要使用 ${xxx} 包围起来。以 BUILD_NUMBER 这个内置环境变量举例来说明就是这样滴:

如果你在 Jenkins 文件中使用 shell 命令,使用这些内置环境变量甚至可以不用 {}, 来看一下:
pipeline {
agent any
stages {
stage("Read Env Variables") {
steps {
echo "带 env 的读取方式:${env.BUILD_NUMBER}"
echo "不带 env 的读取方式:${BUILD_NUMBER}"
sh 'echo "shell 中读取方式 $BUILD_NUMBER"'
}
}
}
}
可以看到结果是一样一样滴,不管有几种,记住第一种最稳妥

内置的环境变量虽好,但也不能完全满足我们自定义的 pipeline 的执行逻辑,所以我们也得知道如何定义以及使用自定义环境变量
自定义 Jenkins 环境变量
Jenkins pipeline 分声明式(Declarative)和 脚本式(imperative)写法,相应的环境变量定义方式也略有不同,归纳起来有三种方式:

还是看个实际例子吧:
pipeline {
agent any
environment {
FOO = "bar"
}
stages {
stage("Custom Env Variables") {
environment {
NAME = "RGYB"
}
steps {
echo "FOO = ${env.FOO}"
echo "NAME = ${env.NAME}"
script {
env.SCRIPT_VARIABLE = "Thumb Up"
}
echo "SCRIPT_VARIABLE = ${env.SCRIPT_VARIABLE}"
withEnv(["WITH_ENV_VAR=Come On"]) {
echo "WITH_ENV_VAR = ${env.WITH_ENV_VAR}"
}
}
}
}
}
来看运行结果:

注意:
withEnv(["WITH_ENV_VAR=Come On"]) {}这里的 = 号两侧不能有空格,必须是key=value的形式
一个完整的 pipeline 通常会有很多个 stage,环境变量在不同的 stage 有不同的值是很常见的,知道如何设置以及读取环境变量后,我们还得知道如何重写环境变量
重写 Jenkins 环境变量
Jenkins 让人相对困惑最多的地方就是重写环境变量,但是只要记住下面这三条规则,就可以搞定一切了
withEnv(["WITH_ENV_VAR=Come On"]) {}内置函数的这种写法,可以重写任意环境变量- 定义在
environment {}的环境变量不能被脚本式定义的环境变量(env.key="value")重写 - 脚本式环境变量只能重写脚本式环境变量
这三点是硬规则,没涵盖在这 3 点规则之内的也就是被允许的了

三条规则就有点让人头大了,农夫选豆种,举例为证吧
pipeline {
agent any
environment {
FOO = "你当像鸟飞往你的山"
NAME = "Tan"
}
stages {
stage("Env Variables") {
environment {
// 会重写第 6 行 变量
NAME = "RGYB"
// 会重写系统内置的环境变量 BUILD_NUMBER
BUILD_NUMBER = "10"
}
steps {
// 应该打印出 "FOO = 你当像鸟飞往你的山"
echo "FOO = ${env.FOO}"
// 应该打印出 "NAME = RGYB"
echo "NAME = ${env.NAME}"
// 应该打印出 "BUILD_NUMBER = 10"
echo "BUILD_NUMBER = ${env.BUILD_NUMBER}"
script {
// 脚本式创建一个环境变量
env.SCRIPT_VARIABLE = "1"
}
}
}
stage("Override Variables") {
steps {
script {
// 这里的 FOO 不会被重写,违背 Rule No.2
env.FOO = "Tara"
// SCRIPT_VARIABLE 变量会被重写,符合 Rule No.3
env.SCRIPT_VARIABLE = "2"
}
// FOO 在第 37 行重写失败,还会打印出 "FOO = 你当像鸟飞往你的山"
echo "FOO = ${env.FOO}"
// 会打印出 "SCRIPT_VARIABLE = 2"
echo "SCRIPT_VARIABLE = ${env.SCRIPT_VARIABLE}"
// FOO 会被重写,符合 Rule No.1
withEnv(["FOO=Educated"]) {
// 应该打印 "FOO = Educated"
echo "FOO = ${env.FOO}"
}
// 道理同上
withEnv(["BUILD_NUMBER=15"]) {
// 应该打印出 "BUILD_NUMBER = 15"
echo "BUILD_NUMBER = ${env.BUILD_NUMBER}"
}
}
}
}
}
来验证一下结果吧


看到这,基本的设置应该就没有什么问题了,相信你也发现了,Jenkins 设置环境变量和编程语言的那种设置环境变量还是略有不同的,后者可以将变量赋值为对象,但 Jenkins 就不行,因为在 Jenkins 文件中,所有设置的值都会被当成 String, 难道没办法应用 Boolean 值吗?
Jenkins 中使用 Boolean 值
如果设置一个变量为 false ,Jenkins 就会将其转换为 "false", 如果想使用 Boolean 来做条件判断,必须要调用 toBoolean() 方法做转换
pipeline {
agent any
environment {
IS_BOOLEAN = false
}
stages {
stage("Env Variables") {
steps {
script {
// Hello 会被打印出来,因为非空字符串都会被认为是 Boolean.True
if (env.IS_BOOLEAN) {
echo "Hello"
}
// 真正的 Boolean 比较
if (env.IS_BOOLEAN.toBoolean() == false) {
echo "日拱一兵"
}
// 真正的 Boolean
if (!env.IS_BOOLEAN.toBoolean()) {
echo "RGYB"
}
}
}
}
}
}
来看运行结果:

如果你写过 Pipeline,你一定会知道,写 Pipeline 是离不开写 shell 的,有些时候,需要将 shell 的执行结果赋值给环境变量,Jenkins 也有方法支持
Shell 结果赋值给环境变量
实现这种方式很简单,只需要记住一个格式:sh(script: 'cmd', returnStdout:true)
pipeline {
agent any
environment {
// 使用 trim() 去掉结果中的空格
LS_RESULT = "${sh(script:'ls -lah', returnStdout: true).trim()}"
}
stages {
stage("Env Variables") {
steps {
echo "LS_RESULT = ${env.LS_RESULT}"
}
}
}
}

总结
关于 Jenkins 环境变量,了解这些基本上就满足绝大多数应用场景了,当再遇到环境变量问题时,可以回过来翻看一下了,有解决的困惑吗?
个人博客:https://dayarch.top
加我微信好友, 进群娱乐学习交流,备注「进群」
欢迎持续关注公众号:「日拱一兵」
- 前沿 Java 技术干货分享
- 高效工具汇总 | 回复「工具」
- 面试问题分析与解答
- 技术资料领取 | 回复「资料」
以读侦探小说思维轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......

10分钟搞定让你困惑的 Jenkins 环境变量的更多相关文章
- 【转】让你10分钟搞定Mac--最简单快速的虚拟安装
文章出处:让你10分钟搞定Mac--最简单快速的虚拟安装http://bbs.itheima.com/thread-106643-1-1.html (出处: 黑马程序员训练营论坛) 首先说明一下. 第 ...
- OpenCV3.4.1快速集成到Android studio中,10分钟搞定
OpenCV3.4.1快速集成到Android studio中,10分钟搞定 转载 https://blog.csdn.net/yu540135101/article/details/8259 ...
- Python基于VS2013 开发环境搭建 Hello World 10分钟搞定
1.先下载Python 安装 Next ->安装完成 2.以前安装过VS2013 打开VS2013 文件->新建项目 (此时如果没有Python Application,请点击里面的安装插 ...
- 10分钟搞定 Java 并发队列好吗?好的
| 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...
- 【前端知识体系-JS相关】10分钟搞定JavaScript正则表达式高频考点
1.正则表达式基础 1.1 创建正则表达式 1.1.1 使用一个正则表达式字面量 const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi; 1.1.2 调用RegExp对象的构 ...
- 10分钟搞定nginx实现负载均衡
10.1 负载均衡的概念 对用户请求的数据进行调度的作用 对用户访问的请求网站可以进行压力的分担 10.2 常见的代理方式 10.2.1 正向代理 10.2.2 反向代理 10.3 负载均衡的部署环节 ...
- 10分钟搞定react-router
1.路由的安装: $ npm install -S react-router 2.引入路由文件 import {Router, Route, browserHistory} from 'react-r ...
- 10分钟搞定webpack打包
入门前端这个职位近三年的时间了,但是脑子里的东西不多也不少,今天就从脑袋里把新版本的webpack打包过程拔出来给大家鲁一遍,就算帮助那些小白了,废话不多说,开始鲁起来,大家跟着我一起撸... 首先, ...
- 一分钟搞定Java高频面试题
一分钟搞定Java高频面试题 一.变量赋值和计算 题目: public static void main(String[] args) { int i = 1; i = i++; int j = i+ ...
随机推荐
- PyQt学习随笔:Qt中tem Views(Model-Based)和Item Widgets(Item-Based)控件的用途和关系
在界面程序开发中,数据的展示主要包括表格.简单列表.树状列表以及纯文本等多种方式,在Qt中将界面表格.简单列表.树状列表称为"表项视图类(item view class)",并提供 ...
- PyQt(Python+Qt)学习随笔:Qt Designer中部件的autoFillBackground属性
autoFillBackground属性可以确认部件背景是否自动填充,如果自动填充,Qt会在调用Paint事件之前填充部件的背景.使用的颜色由部件调色板中的QPalette.window 角色定义(关 ...
- PLSQL Developer 工具应用
用户scott使用: 解锁scott: 第一步:登陆管理员 SQL语句:Sqlplus sys/tiger as sysdba 第二步:解锁scott SQL语句:Alter user scott a ...
- (转)MySQL优化原理
原文:https://mp.weixin.qq.com/s__biz=MzI4NTA1MDEwNg==&mid=2650763421&idx=1&sn=2515421f09c1 ...
- java springboot@GeneratedValue 注解
springboot中@GeneratedValue作用: (1)@GeneratedValue注解存在的意义主要就是为一个实体生成一个唯一标识的主键.@GeneratedValue提供了主键的生成策 ...
- Codeforces Edu Round 49 A-E
A. Palindromic Twist 由于必须改变.所以要使\(a[i] = a[n - i + 1]\). 要么同向走,但必须满足之前的\(a[i] = a[n - i + 1]\). 要么相遇 ...
- 写了两年的一本.NET书现在终于在北京最大的新华书店上架了,然而我却很难找到工作了。
两年前,有几个出版社的编辑在QQ上跟我联系写书的事情,好奇为什么出版社会找到我这样一个很普通的.NET技术人员,其中一个编辑说他们分析了很多博客园博主的文章阅读量和写作质量,觉得我的博客还是不错的.尽 ...
- Jmeter之登录接口参数化实战
为了纪念我走过的坑(为什么有些简单的问题就是绊住我了,还是不够细啊) Jmeter之接口登录参数化实战 因为想要在登录时使用不同的数据进行测试,所以我选择了将数据进行参数化.因为涉及到新建一个接口的功 ...
- ssl证书---验证域名数量分类
单域名SSL证书 : 单一域名 多域名SSL证书 : 多个域名 通配符SSL证书 : 通配符域名
- canvas可视化效果之内阴影效果
canvas可视化效果之内阴影效果 楔子 在之前的一个轨道交通可视化项目中,运用到了很多绘制技巧. 可以参考 之前的一篇文章 <利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果> ...