admin 管理员组

文章数量: 1184232

目录

基本概念

用途之一

环境变量表

命令行参数表

理解

更多的环境变量

本地变量

获取环境变量的方法

指令操作

代码操作

方法一

方法二

方法三

总结


基本概念

  • 环境变量(environmentvariables)⼀般是指在操作系统中⽤来指定操作系统运⾏环境的⼀些参数
  • 环境变量通常具有某些特殊⽤途,还有在系统当中通常具有全局特性

用途之一

我们看一个之前说到过的问题:

为什么直接敲指令可以直接运行,而我们自己写的程序却要写路径才能运行?

现象:


我们之前说只需要我们把自己的可执行文件放进/usr/bin/目录下就可以不带路径,但是为什么呢?

这是因为有环境变量。

有一个可执行文件,要运行它,必须要先找到它吧,我们带上路径就能执行,而不带却不能执行,但是系统中的指令却不用带就能执行,为什么?

系统中有一个名叫PATH的环境变量,帮助系统找到可执行的二进制文件!PATH中存着/usr/bin路径(当然不止这一个路径),系统会默认到PATH中的路径寻找输入的指令,如果查遍了PATH中的所有路径都没有查到输入的指令,那么就报错反馈给用户,如果查到了,执行即可!

查所有环境变量,指令:

env

是以名称=内容的形式存放的。

查某个环境变量内容,指令:

ehco $(需要查找的环境变量名)

可以将自己的可执行文件放到PATH路径中,但是我们也可以添加路径到PATH中,这样我们可以解决:

当我们把PATH路径全部修改掉,原来系统指令就执行不了了,但有些内命令能运行,这个内建命令我们后面讲:

我们修改后,不知道怎么恢复,可以直接退出重新登陆,即可恢复原样。

环境变量表

环境变量是怎么来的呢?怎么理解它?它是怎么被存储的?

我们登陆上去,bash从系统中的相关配置文件(shell脚本写的)读取,形成一张环境变量表(数组),也就是说系统中环境变量都在bash的这张环境变量表中!

如果同时登陆10个用户呢?也就是有10个bash,它们都会形成各自的环境变量表(从相关配置文件中读取的)。

环境变量表的存储:

将环境变量以字符串的形式存入环境变量表。

命令行参数表

除了环境变量表,其实还有一张命令行参数表!

在日常生活中,我们常常使用一些命令达不到我们的需求,所以指令一般都有一些参数来实现多功能的需求。

例:

理解:

在bash看来我们敲的一行行指令就是一个字符串,bash将这一个个命令参数切分,放入命令参数表中,通过表上的不同的命令参数执行不同的功能。

理解

直观的看命令行参数表:

命令行参数表其实就是个字符串数组!(main函数最多有三个参数)

有这个命令参数表,我们可以将不同参数实现不同功能:

直观的看环境变量表:

环境变量表和命令行参数表一样是个字符串数组!

综合理解:

我们一登陆,bash读取OS相关配置文件,填写形成环境变量表,当我们敲一个命令时,bash读取命令行,将命令行切分,填写形成命令行参数表,bash会在PATH环境变量的所有路径中,寻找这个指令,如果有,根据参数,运行这个多功能的指令!如果没有,报错给用户。也就是说bash会存在两张表。

有个问题:

这个myprocess进程是bash的子进程,我们说环境变量只是在bash中,怎么这个myprocess进程可以拿到呢?

我们开始讲概念的时候说过,环境变量是具有全局属性的,也就是说,bash中的环境变量表是被子进程继承的,别说子进程,哪怕是bash的孙子进程,曾孙进程也是继承的,具有全局特性!

理解:

我们以为程序的入口是main函数,其实,main函数上一层还有一个start函数,start函数调用main函数,只不过我们看不到start函数,只能看到main函数,所以才以为main函数是程序的入口。

main函数可以是0/1/3个参数,start将参数传入子进程main函数,也就是说start函数是将bash中的环境变量表,命令行参数表传入子进程main函数。

更多的环境变量

我们可以看到有很多个环境变量,现在我们来说说一些常见的。

HOME环境变量

我们可以看到当用户是root用户,HOME变量就是root的家目录,是普通用户,HOME变量就是普通用户的家目录,也就是说HOME变量存放的是当前用户的家目录。

其实就是因为有HOME变量才能迅速切换到当前用户的家目录。

SHELL环境变量

代表登陆时是用的哪个版本的bash。

USER环境变量

记录着是哪个谁登陆的。

HISTSIZE环境变量

我们知道我们可以查到我们输入的历史命令,但是只能查到最近的1000条,bash只会记录最近的1000条,因为默认情况下HISTSIZE设置成1000条。

存放着历史命令数量限制。

HOSTNAME环境变量


存着主机名。

SSH_TTY环境变量

表示当前是哪个终端设备。

LS_COLORS环境变量

存放着配色方案。

PWD和OLDPWD环境变量

PWD存放着当前目录,OLDPWD存放着最近的目录。

我们知道我们使用cd - 命令就能回到历史的最近目录,也就是工作目录的切换:

本地变量

不仅有环境变量,其实还有本地变量的概念,bash有两套变量,一个是环境变量,一个是本地变量。

本地变量是不被子进程继承,只在bash内部使用,这是和环境变量本质区别。

操作

我们可以用set指令,用来打印环境变量和本地变量:

也可以echo打印本地变量:

删除某个本地变量:

可以利用export指令将本地变量导入环境变量:

验证本地变量不被继承:

自己写一个打印环境变量表的子进程,看看结果:

获取环境变量的方法

指令操作

我们上面演示过一些指令可以查找环境变量。

比如env:显示所有环境变量,echo $某个环境变量名 :查找某个环境变量。

可以使用export指令来添加一个环境变量。

有一个问题:

按照我们的理解,export指令运行起来是个进程,也是bash的一个子进程,我们也知道,父子进程是相互独立的,并且环境变量表是在bash中的,问题是,为什么子进程可以修改父进程的信息呢?

有一个内建命令的概念(bulit-in command),这种命令不需要创建子进程,而是bash亲自执行(bash调用系统调用或函数实现)。显然export就是这样一个内建命令。

删除某个环境变量(unset指令):

代码操作

方法一

利用父进程bash的环境变量表和环境变量具有全局性的特性,来一个一个输出打印(我们先前演示过的!)

方法二

利用getenv函数,getenv函数的作用就是得到某个环境变量的地址。

其实,我们也可以通过这个函数来控制只有某个用户才能看到这个程序的结果,而其他用户看不到!

方法三

利用全局变量访问环境环境变量表,先前说过有一个全局变量environ指向环境变量表。

同时我们可以继续验证一下环境变量表的全局特性!

bash进程有子进程myprocess,fork一下,myprocess也有子进程,然后这个子进程跑fork()==0的条件代码,没报错有结果,侧面验证了环境变量表的全局特性!

总结

有这三个方法访问环境变量表,但是我们只推荐方法二!

好了,我们下期见!

本文标签: 环境变量 系统