Linux操作系统——进程(五)环境变量
环境变量
有了我们前面的命令行参数的理解基础呢,我们下面进入环境变量这一个部分的内容的学习。
一般在我们安装一些开发工具尤其是有解释器的开发工具的时候,我们呢一般都要配置环境变量,可能都不太清楚自己为什么要配置环境变量?
一般呢,大家稍微注意一下就能够知道一般我们都会给什么Java的JDK啊,python的解释器,或者eclipse,IDEA进行配置环境变量。
那么我们前面写了个我们自己的touch命令发现我们自己写的touch命令在运行的时候需要带上./mytouch才能运行,而系统命令是自己输入命令+选项就可以直接运行了。

其实这就是跟我们的环境变量有关系了。
首先要执行我们的命令,就必须要先找到命令所对应的可执行程序!
而之所以我们运行我们自己写的touch命令的时候需要带上./的原因就是告诉系统,我们要执行的可执行程序就在当前目录下,其实我们的系统命令为什么没有带上找到他的路径呢?其实系统命令也可以通过给出搜索路径来进行执行命令,那么不用带搜索路径说明系统就一定有它默认的搜索路径

我们发现系统命令也可以带路径执行,也可以不带路径执行,而我们自己的可执行程序不带./的话发现我们的bash找不到该命令。
所以呢,在Linux当中会有一个环境变量通过指令echo $PATH查看环境变量,可以记录我们的可执行程序的搜索路径。

打印出来了一长段的字符串,每一个子串其实就是可执行程序的搜索路径,这些可执行程序的路径都是以:作为分隔符,那么假设我们输入一条命令ls,系统会以:作为分隔符在这些搜索路径中进行查找是否有对应的可执行程序,如果找到了那么当然就可以直接运行了,如果没有找到那就会出现如下一条提示:
![]()
命令没有找到。
那么我们如何添加这里的环境变量呢?
通过输入命令:PATH=$PATH: 可执行程序的搜索路径
例如:

发现我们的可执行程序搜索路径配置好了环境变量,此时可以直接输入mytouch命令可以不用再带./,当然带上./也能正常运行,这样就可以理解为什么系统指令不用带路径执行了。

我们可以看到通过配置之后,指令可以正常运行了。
那么如果我们不想要该环境变量怎么办呢?
可以通过给PATH重新赋值:

此时我们的环境变量又改过来了,我们运行mytouch 可执行程序发现:

又只能用./方式运行了,因为我们没有给该可执行程序配置环境变量,也就是可执行程序的默认搜索路径。
在我们的xshell当中,默认更改环境变量只限于本次登录,重新登陆环境变量会被自动恢复。
下面我们修改代码为如下所示:

我们只对可执行程序进行打印就行了。
我现在呢不想把我们的可执行程序的路径添加到我们的环境变量里,我们就想把我们的可执行程序给拷贝到我们的系统路径下。下面通过执行如下操作就能够将该可执行程序拷贝到系统路径下:

这种操作需要提高你的权限所以前面我们需要加一个sudo,执行完之后我们which mytouch就可以看到我们的可执行程序就被成功的拷贝到系统目录下了:

然后我们执行mytouch命令:

这样呢跟我们所执行的ls系统命令就没有什么区别了,就不需要带./,可以用which来查看该命令所在的路径了。像这种操作我们可以把它称之为程序安装。
![]()

上面我们执行上述sudo rm /usr/bin/mytouch把该可执行程序从系统目录中删除就叫做程序卸载。
我们发现再去执行该命令就执行不了了。
现在呢我们改环境变量只是临时的去修改环境变量,那这些环境变量一开始是从哪里来的呢?我们还没开机呢?我们也会进行重启啊,那么PATH里为什么就默认有那些路径呢?那如果我想要让我们的环境变量永久有效呢?
所以,我们的环境变量并不是单纯的在内存中创建的,它一定是从某些配置文件中去读取的,其实我们的系统中呢会存在很多的配置文件,有一类配置文件是在我们命令行启动的时候会把我们预设的环境变量和变量的值给我们导入进来的,所以为什么我们改了之后会重启我们的xshell之后他又会失效,原因就在于重新登录之后系统是会重新从配置文件中去读取这些环境变量的。
下面我们再认识一个环境变量:PWD

系统他怎么知道我们在当前哪个路径呢?我们执行pwd能够将我们当前所在的路径打印出来,然后我们进入上一级目录之后再pwd发现打印的路径也随之改变了。
其实呢系统中有这么一个环境变量:PWD专门为bash内置的用来记录我们当前所处的路径的一个字段,而我们的pwd命令只需要读取PWD将其打印出来就可以了。

下面我们再说一个环境变量:HOME

为什么普通用户所处家目录默认是/home/XXX呢?
为什么root用户所处的家目录默认是/root呢?
原因就在于系统中一定有一个环境变量,这个环境变量比我们登录还要早,在我们登陆的时候呢可以识别出我们的用户,因为我们登录的时候是输入了用户名的,然后可以识别到我们是普通用户还是root用户。然后形成对应的环境变量。然后根据用户名初始化我们的环境变量。
登录的时候:
1.输入用户名和密码
2.认证
3.认证通过后会形成环境变量(肯定不止一个,PATH,PWD,HOME).
3.1根据用户名初始化HOME=/home/XXX,HOME=/root
4.cd $HOME
上面我们已经了解了三个环境变量PATH,PWD,HOME.
其实环境变量有很多,那么我们如果想要查看系统默认初始化的所有的环境变量我们该如何查看呢?
我们可以通过执行命令:env
可以看到很多的键值对的形式“=”左右两边分别为环境变量的键和值的形式显示。


目前呢我们当前是普通用户,我们可以看到目前USER是这个,那么当我们切换用户为root之后:

那么我们的环境变量就被初始化成了root.
我们的系统中会存在大量的环境变量,每一个环境变量都有它自己的特殊用途, 用来完成特定的系统功能!
通过代码如何获取环境变量?
我们可以通过man getenv查看这个系统调用接口来获取环境变量

我们编写如下代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{printf("PATH:%s\n",getenv("PATH")); return 0;
}
运行结果:

当然我们也可以把PATH改成其他想要获取的环境变量名称:
比如说改成USER
运行结果:

其实呢,系统会自动的给我们创建一张环境变量表的东西:

下面我们写一段这样的程序来打印我们的环境变量:

运行之后:

发现我们运行的结果与我们前面用env命令获取的结果基本上是一样的。
我们命令行启动的进程都是shell/bash的子进程,子进程的命令行参数和环境变量,是父进程bash给我们传递的!
子进程的环境变量是父进程传递的,那么父进程的环境变量又是从哪里来的呢?
我们前面说到更改环境变量问题,其实我们直接更改的是bash 进程内部的环境变量信息!而我们用户的每一次登录,都会给我们形成的新的bash解释器,并且新的bash 解释器会自动从某个配置文件自己的环境变量 表信息!
这里所说的配置文件就是

我们家目录下的一个隐藏文件 .bash_profile
我们可以用vim打开这个文件:

所以呢我们就可以知道环境变量信息是以脚本配置文件的形式存在的!
每一次登录的时候,我们的bash进程都会读取.bash_profile配置文件中的内容,为我们的bash进程形成一张环境变量表信息!
如何证明上述结论呢?
下面我们通过自己定义一些环境变量,例如:

我们定义一个环境变量名为:MYENV_109 值为:hellolinux
当我们echo $MYENV_109的时候是有内容的,可是当我们用env命令查看该环境变量是否能够添加到环境变量表当中运行之后发现并没有添加,我们把这样定义的环境变量叫做本地变量。

当我们打印的时候环境变量是有值的,而当我们用我们上面写的代码形成的可执行程序来运行获取环境变量时发现获取不到。
那么如何把我们自己定义的该环境变量导入到环境变量表当中呢?
我们通过export+环境变量名将我们的环境变量导入到环境变量表当中,那么我们的env命令和我们的可执行程序就都能获取该变量的了。

虽然这样可行了,但是当我们把xshell退出之后重新登录之后,获取我们刚刚导入的环境变量发现又不见了,原因就在于我们刚刚导入的环境变量仅仅只是在当前bash进程中修改的,根据我们上面的结论,bash进程在我们重新登录之后又会重新在我们的配置文件中取读取我们的环境变量,所以我们先前添加的环境变量会失效。

当我们重新登录后发现果然这个环境变量不见了,那么我们应该如何永久的导入一个环境变量呢?
那当然是通过在配置文件.bash_profile文件中添加shell脚本了,我们可以通过编辑该配置文件为如下:
修改前:

修改后:

我们添加了上述代码,然后保存退出,然后呢要想让该环境变量生效我们还需要重新登录让bash再重新读取一次该配置文件,然后登录成功之后:
我们查看一下这个配置文件的内容:

在执行上述语句发现已经生效了。

我们上面谈到,子进程的环境变量是由父进程进行传递的,那么我们父进程的环境变量就会一直被传递下去,所以以该父进程为根节点,所有由该父进程创建的子进程,再由子进程继续创建子进程的子进程都能够共享到该父进程的环境变量,所以我们说系统环境变量具有全局属性!!!
除了上述获取环境变量的方式其实还有一种方式可以获取到环境变量,我们c语言给我们提供了一个全局变量名字叫 environ
下面我们可以通过修改我们之前的代码实现:

运行结果:

可以发现我们刚刚添加再配置文件中的环境变量也被获取了。
所以我们就知道三种获取环境变量的方式了:
1. env命令
2.main函数传参
3.C语言提供的全局变量:environ
我们上面又谈到过一个本地变量,那么本地变量和我们的全局变量有什么区别呢?
本地变量vs环境变量
本地变量只在bash进程内部有效,不会被子进程继承下去。
环境变量通过让所有的子进程继承的方式,实现自身的全局性!

我们发现当我们创建本地变量的时候,我们可以通过echo命令将本地变量的值给打印出来,但是我们的命令也是进程啊,按照这样的逻辑来说的话,当我们执行echo命令的时候是通过bash来创建子进程运行的,但是我们上面又说本地变量只在bash进程内有效,不会被子进程继承下去,那你这不是在跟我扯嘛?
其实啊,这里要跟大家说一下,我们的Linux中命令是由分类的,诸如我们上面用到的echo命令,export命令都是内建命令,而需要创建子进程的命令是我们的常规命令:
Linux命令分类:
1.常规命令:shell fork让子进程执行的命令
2.内建命令,shell命令行的一个函数,不会创建子进程,当然可以直接读取shell的本地变量喽。
和环境变量相关的命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
环境变量的组织方式

每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串。
相关文章:
Linux操作系统——进程(五)环境变量
环境变量 有了我们前面的命令行参数的理解基础呢,我们下面进入环境变量这一个部分的内容的学习。 一般在我们安装一些开发工具尤其是有解释器的开发工具的时候,我们呢一般都要配置环境变量,可能都不太清楚自己为什么要配置环境变量…...
西门子博途怎么使用PID_Compact做pid调试
到目前为止,我已经在S7-1200中创建了一个可运行的PLC程序,并在Basic Panel中创建了一个HMI项目来操纵和操作该程序。 引文:博途工控人平时在哪里技术交流博途工控人社群 现在,我们该如何深入的让程序开始逐渐智能化呢,…...
结构型模式 | 适配器模式
一、适配器模式 1、原理 适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式主要分为三类:类适配器模式、对象适配器模式、接口…...
基于Python的车牌识别系统实现
本文将以基于Python的车牌识别系统实现为方向,介绍车牌识别技术的基本原理、常用算法和方法,并详细讲解如何利用Python语言实现一个完整的车牌识别系统。 精彩专栏持续更新推荐订阅,收藏关注不迷路 微信小程序实战开发专栏 目录 引言车牌识别…...
时间序列预测模型介绍及使用经验总结
1. 时序预测背景 时序数据,就是序列随时间变化的数据。时间序列分析,一般有时域和频域两种分析方法。时序预测的本质是在时域和频域层面探索时间序列变化的内在规律。 下图描述的是时域(temporal domain),横坐标是时…...
Docker知识总结
文章目录 Docker1 Docker简介1.1 什么是虚拟化1.2 什么是Docker1.3 容器与虚拟机比较1.4 Docker 组件1.4.1 Docker服务器与客户端1.4.2 Docker镜像与容器1.4.3 Registry(注册中心) 2 Docker安装与启动2.1 安装Docker2.2 设置ustc的镜像2.3 Docker的启动与…...
算法训练营Day25
#Java #回溯 开源学习资料 Feeling and experiences: 复原IP地址:力扣题目链接 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。 例如࿱…...
docker笔记2-docker 容器
docker 容器的运行 docker run 镜像名:版本标签: 创建 启动容器 docker run 镜像名 ,如果镜像不存在,则会在线下载镜像。 注意事项: 容器内的进程必须处于前台运行状态,不能后台(守护进程运行…...
redis 从0到1完整学习 (七):ZipList 数据结构
文章目录 1. 引言2. redis 源码下载3. zipList 数据结构3.1 整体3.2 entry 数据结构分析3.3 连锁更新 4. 参考 1. 引言 前情提要: 《redis 从0到1完整学习 (一):安装&初识 redis》 《redis 从0到1完整学习 (二&am…...
2015年第四届数学建模国际赛小美赛C题科学能解决恐怖主义吗解题全过程文档及程序
2015年第四届数学建模国际赛小美赛 C题 科学能解决恐怖主义吗 原题再现: 为什么人们转向恐怖主义,特别是自杀性恐怖主义?主要原因是什么?这通常是大问题和小问题的结合,或者是一些人所说的“推拉”因素。更大的问题包…...
基于Java开发的微信约拍小程序
一、系统架构 前端:vue | element-ui 后端:springboot | mybatis 环境:jdk8 | mysql8 | maven | mysql 二、代码及数据库 三、功能说明 01. 首页 02. 授权登录 03. 我的 04. 我的-编辑个人资料 05. 我的-我的联系方式 06. …...
蓝桥杯的学习规划
c语言基础: Python语言基础 学习路径:画框的要着重学习...
EMC噪声的本质
01 频谱的含义 频谱是将电磁波分解为正弦波分量,并按波长顺序排列的波谱,就是将具有复杂组成的东西分解(频谱分析仪)为单纯成分,并把这些成分按其特征量的大小依序排列(部分不计),…...
Redis遇到过的问题 (Could not get a resource from the pool )
生产上通过scan命令,查询一个大key耗时40s后,报 Could not get a resource from the pool,初步报错是连接池的连接数不够,从网上搜了一些解决方案。 排查过程: 一、首先需要先尝试连接redis,如果连接不上那…...
Spring Boot 3.2 新特性之 HTTP Interface
SpringBoot 3.2引入了新的 HTTP interface 用于http接口调用,采用了类似 openfeign 的风格。 具体的代码参照 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-http-interface 一、概述 HTTP Interface 是一个类似于 openfeign 的同步接口调…...
Flask+Mysql项目docker-compose部署(Pythondocker-compose详细步骤)
一、前言 环境: Linux、docker、docker-compose、python(Flask)、Mysql 简介: 简单使用Flask框架写的查询Mysql数据接口,使用docker部署,shell脚本启动 优势: 采用docker方式部署更加便于维护,更加简单快…...
DDOS攻击简介——什么是DDOS
DDoS是什么? DDoS是分布式拒绝服务攻击(Distributed denial of service attack)的简称。 分布式拒绝服务器攻击(以下均称作DDoS)是一种可以使很多计算机(或服务器)在同一时间遭受攻击,使被攻击的目标无法正常使用的一种网络攻击方式。DDoS攻击在互联网上已经出现过…...
龙蜥开源操作系统能解决CentOS 停服造成的空缺吗?
龙蜥开源操作系统能解决CentOS 停服造成的空缺吗? 本文图片来源于龙蜥,仅做介绍时引用用途,版权归属龙蜥和相关设计人员。 一、《国产服务器操作系统发展报告(2023)》称操作系统已步入 2.0 时代,服务器操作…...
『Linux升级路』基础开发工具——gdb篇
🔥博客主页:小王又困了 📚系列专栏:Linux 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、背景知识介绍 二、gdb指令介绍 一、背景知识介绍 在软件开发中,…...
边缘计算云边端全览—边缘计算系统设计与实践【文末送书-10】
文章目录 一.边缘计算1.1边缘计算的典型应用 二.边缘计算 VS 云计算三.边缘计算系统设计与实践【文末送书-10】3.1 粉丝福利:文末推荐与福利免费包邮送书! 一.边缘计算 边缘计算是指在靠近物或数据源头的一侧,采用网络、计算、存储、应用核心…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
