百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

10分钟搞定让你困惑的 Jenkins 环境变量

myzbx 2025-03-14 19:07 34 浏览

前言

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

  1. 找到终端的临时密码登陆
  2. 安装推荐的依赖
  3. 创建新的 Pipeline 类型的 Item
  4. 点击左侧 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 让人相对困惑最多的地方就是重写环境变量,但是只要记住下面这三条规则,就可以搞定一切了

  1. withEnv(["WITH_ENV_VAR=Come On"]) {} 内置函数的这种写法,可以重写任意环境变量
  2. 定义在 environment {} 的环境变量不能被脚本式定义的环境变量(env.key="value")重写
  3. 脚本式环境变量只能重写脚本式环境变量

这三点是硬规则,没涵盖在这 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 环境变量,了解这些基本上就满足绝大多数应用场景了,当再遇到环境变量问题时,可以回过来翻看一下了,有解决的困惑吗?

趣味原创解析Java技术栈问题,将复杂问题简单化,将抽象问题图形化落地如果对我的专题内容感兴趣,或抢先看更多内容,欢迎访问我的博客 dayarch.top

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...