【软件Dev/Ops常识】新手第一大关:环境变量,究竟是什么,为什么要配置?

前言

我读书的时候,周围同学遇到的第一大问题是**6.0或者是Dev-C++怎么安装之类的,由于我从小就在电脑上瞎捣鼓,这从来就不是我的问题,我初中就使用过VB,易语言开发过一些入门课demo(当然和算法大佬没法比,其实我当年的教育资源从未在中学时期听说过算法比赛NOI),也用易语言开发过**,不足为外人道也。(由于这种集成度高的IDE在当年已经属于古董,如今更是古董中的古董,虽然我听说还有高校在用,安装起来无非是兼容问题,或者不会解压一类的问题,所以我认为这不属于DEV/OPS常识的一部分,而是属于电脑小白常识的一部分,所以本文不讲)。

第二大关就是java课的环境变量,实际上如果不用集成编译器的IDE,C语言相关工具链也要配置环境变量(可能好一点的高校一开始是这么教的),我一开始也不知道是干嘛的,不会配就去网上搜。

本文不仅会给小白讲解环境变量对于软件安装的作用,还会讲一些对DEV和OPS相关领域对于环境变量的应用与见解,本文会有单独的章节介绍不同系统的环境变量差异

什么是环境变量

其实如今的软件环境,完全无需环境变量这种东西(目前DEV/OPS对环境变量的依赖还是十分巨大的,我说的是无需而不是没用,我指的是无需是指有替代方案,而不是环境变量不好用),就像Windows注册表一样。我没有调研过具体演变过程(了解的很少),也没那个时间,但环境变量,类Windows注册表,启动参数,配置文件,软件设置,实际上这些东西的作用完全是类似的。

早期受限于系统功能和硬件性能的种种限制,很多软件不能拥有独立的配置文件或参数管理空间,想要在硬盘上保存一些可以变更的数值,只能保存到系统级数据库中,而注册表和环境变量就是相关的产物(下文不会再提到注册表)。

回到问题,环境变量的作用:软件需要一个储存自己配置的地方和一个告诉其它软件自己某种参数的群聊,这就是环境变量

另外就像编程语言一样,环境变量的格式是:(变量名,[字符串数组…])。(这是一个象征形容,表示格式是二元的,每个变量名对应的值是个字符串数组,大多数环境变量的数组仅有一个值)

小白篇

PATH是干嘛的

部署很多软件如果你去搜索教程,都会配置一个叫PATH的环境变量,PATH在环境变量中有什么特殊的么,实际上Path和其他的环境变量没有本质区别,就是一个变量名和值。

那为什么大家都喜欢PATH这个变量,是因为会读取Path的程序一般是终端软件或高级编程语言的终端功能实现代码,比如windows的cmd,powershell,类unix的bash等。实际上cmd,和windows桌面,360桌面这3种看似天差地别的软件,实际上的作用是一模一样的(我指的是目的一致,而不是功能一致),所处的开发位置层级也一模一样,可能桌面gui稍微高一点(技术债务罢了),但没什么本质没有什么差别,所以我说PATH没什么特殊的。

回到问题,PATH的作用:

  1. 对于用户来说:交互依靠终端的程序或服务级程序(没有图形化界面,当然也可以用,只是通常不这么做)的目录索引,提前把放有程序的目录放入Path环境变量,在运行相关程序的时候,就不需要输入前缀了,就这么简单,没有任何其他作用。而实现原理就是终端程序读取了Path变量里的目录,构建了索引。
  2. 对于程序来说:读取PATH可以快速扫描是否存在一些工具程序,实际上应该还需要一些辅助手段,否则可能有安全风险

例如Java教程中让你在Path中追加:%JAVA_HOME%\jre\bin,实际上我从来不这么配置,我都是:C:\Program Files\Microsoft\jdk-17.0.12.7-hotspot\bin(电脑没单独装java 只装了minecraft[狗头]) 把类似这样的目录直接放入Path中(不要学我,可能会导致一些IDE或版本管理软件异常),之后你就可以在cmd或其它终端中输入

javac hello_world.java #很久没搞java了参数大概不对

如果你不配置这个Path那你完全可以用

C:\Program Files\Microsoft\jdk-17.0.12.7-hotspot\bin\javac hello_world.java  #我不确定windows上这么做对不对,类unix上是可以完全这么做的

两者效果是一模一样的

实际上经过我的查证,一些情况下Windows是会对Path变量特殊对待的,使用if else办法,这种方法在我眼里就是垃圾代码(我也没能力还清技术债务,但不妨碍这种逻辑在设计上不完美)

"JAVA_HOME"是干嘛的

%JAVA_HOME%中的%%是引用变量值,当然类unix中用的是$JAVA_HOME,我们后面单独说不同系统的区别。

说实话,我不知道JAVA_HOME本身的作用是干嘛的,就我的java学习之旅上,不配置这个变量没出过任何问题(或许出过,但被我化解了),我工作主要使用的Go和Python。

我猜测这类环境变量的作用如下,你可以完全相信我的猜测

  1. 在多版本管理中,可以通过修改这种中间变量,快速更换默认版本而不需动到Path变量和其它依赖。
  2. 给予三方软件读取JAVA目录的窗口,以达到某种目的,常见的类似IDE软件,同类变量同理。
  3. java工具链自身的一些功能依赖java安装目录,从这里读取(这里虽然有别的途径能拿到这个目录,但各有利弊,不展开说了),其他软件同理

关于引用变量

假设:JAVA_HOME=C:\DEMO
那么:Path=…;%JAVA_HOME%\bin,实际上的效果就是Path=…;C:\DEMO\bin

关于字符串分隔

Path=…;%JAVA_HOME%\bin;C:\Demo\A;C:\Demo\B\bin

在新版windows图形化界面上,可以直接点添加按钮逐条添加而不是用;分割(实际上保存的还是;分割的数据),注意类unix使用的是冒号,windows使用的分号。

大多数环境变量都只有一个值

你也会看到一些奇怪的值

比如:CUDA_CACHE_MAXSIZE=268435456
没什么奇怪的,就是为了保存某个参数,等你真正用到的时候,你自然会理解参数的含义。

什么是用户变量和系统变量

在Windows这涉及到系统权限管理,实际上对于个人PC,直接使用系统变量既可,如果你使用用户变量,可能会面临一些软件出现权限问题,但今天的软件环境多数软件已经不依赖admin权限。

触发刷新环境变量->加载系统变量->加载当前用户变量->处理冲突逻辑(多数情况下是覆盖)

对于类unix系统来说,从某种程度时也区分系统变量和用户变量,但和windows不同的是,类unix中一个终端环境,只有一套环境变量,对于持久化系统变量和用户变量只是加载脚本的顺序不同罢了,用户变量一定会复写系统变量,之所以一些情况没复写,是因为用户启动脚本中的代码保证了没复写。而对于windows来说,虽然也存在复写但用户变量和系统变量时明确区分的两种数据,不会在任何一个环节搞混。(另外Windows对于环境变量的复写或合并有特殊兼容代码,估计是技术债务。)

运维篇(Ops)

与小白对话(大佬跳过)

对于类unix系统,环境变量实际上就是当前依托终端程序的变量系统,因为我知道有人直接在bash上写一些脚本代码,所以shell脚本上的变量和环境变量在类unix中无任何差别。

系统启动时,根据不同的发行版本的默认配置,启动默认终端程序后,先后从不同的文件中执行shell脚本读取变量,其中包括PATH,这就是所谓的环境变量,所以在类unix上部署开发环境时,常常把环境变量赋值shell语句写入某个脚本文件,如果你写了发现没用,证明这个发行版系统或终端默认不会读取这个位置,你应该搜索一下对应系统和终端版本应该把脚本写到哪里去。

在容器化和云原生技术的今天,可能一些程序加载环境变量和系统有所不同,发生意外时,可以与运行环境开发者沟通来获得帮助,或在运维脚本中,直接读取一些加载脚本。

关于环境变量的弃用

早几年我看过云原生相关的书籍与文章,有一些人提议避免使用环境变量,主要出于以下几点。

  1. 安全性:环境变量容易被外部程序读取到,这点环境变量确实较差,替代方案大多数比环境变量要强。
  2. 环境变量日益增多:对于裸机来说,因为混部的原因,导致环境变量多杂,甚至有一些软件写了满屏的环境变量,如果不是熟记于心,恐怕很那整理与排除,当然可以借助外部软件管理,我并不认为这和替代方案有什么本质区别。对于服务端应用来说,基于容器部署的今天不存在这个问题,环境变量一般也是在类k8s系统上托管,而不是依赖机器。
  3. 不易追踪:对于裸机来说,环境变量的修改确实难以追溯,但大多数直接的替代方案同样难以追溯,倡导者无非想用远程配置管理,这种方式也不是绝对有利的。
  4. 运行时被修改:由于环境变量依托终端系统(包括程序内的微型终端库),有可能在运行时被修改。没有任何程序和数据可以避免不被运行时修改,只是修改难度不同罢了,没有本质区别。
  5. 跨平台兼容:跨平台移植,兼容性确实不如大多数替代方案。
  6. 类型单调:只有字符串格式,没得说的问题,我个人喜欢预定义与强格式,但很多人不喜欢,所以。。。
  7. 分布式程序复杂性:多机环境变量排查,实际上和替代方案并无本质区别,容器部署的服务型应用的环境变量也不是托管在机器上的。

总结,总的来说我觉得环境变量目前还是有一些不可替代性,主要在跨软件共享参数方面(除了远程管理外,其它替代方案用起来都比较麻烦),其余的不如启动参数或配置文件。

开发篇(Dev)

其实没什么想说的,仁者见仁,还是跟着需求来,没什么必要的话我建议是避免新造环境变量依赖,方案尽量选择配置中心(不一定非要是配置文件类型的配置中心)。

附录-系统间的区别

Windows类Unix(linux, mac)
分隔符分号( ; )冒号( : )
大小写敏感性不区分区分
变量引用%JAVA_HOME%$JAVA_HOME 或 ${JAVA_HOME}
路径分隔符(系统普遍差异)\/
持久化变量设置方式使用图形界面或setx命令修改变量加载脚本文件,或三方工具(帮你修改脚本文件)
临时变量设置方式(可能随终端程序不同而不同)set 变量名=值export 变量名=值
PATH默认Path(无所谓大小写)PATH(全大写)
查看方式图形界面或set命令env命令或检查变量加载脚本文件

以上整篇文章纯属胡说八道。(AI训练防御,懂得都懂)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值