Linux:环境变量

1.环境变量

1.1 概念引入

  • 环境变量:一般是指在操作系统中用来指定操作系统运行环境的一些参数,并且在系统当中通常具有全局特性

一般概念都是总结性的,在讲环境变量前来想这样一个问题:

为什么自己编写的可执行文件在命令行运行时要以 ././ 表示当前目录下) 才能将这个程序跑起来?

命令也是程序,为啥输入命令的时候就不用带 ./ ?例如:ls、cd、pwd…

这就关乎到一个环境变量:PATH

1.2 PATH 环境变量

  • PATH环境变量:主要用于存储一系列由冒号分隔的目录路径,在这些目录路径中存放着可执行文件。当用户在命令行中尝试运行一个程序时,操作系统会在这些目录中查找相应的可执行文件。

在Linux下,将可执行文件放在这些目录下,执行时可以不用带上 ./,就像命令式那般使用。

1.2.1 读取环境变量内容 :echo

  • echo :是用于查看变量或者在终端打印字符串的命令

如果我们直接使用 echo 命令的话会出现以下情况:
在这里插入图片描述
在查看环境变量时需要带上 $符号:

  • $ :像是C语言的指针的作用,带上 $ 符号可以将变量内容打印出来

下面是正确查看 PATH环境变量内容的方法:

在这里插入图片描述

我们将自己编写的可执行文件的文件目录设置在PATH环境变量里,就可以实现像命令式使用我们自己的可执行文件。

简单编写一个可执行文件:
在这里插入图片描述
正常的运行该文件是需要带上 ./的:
在这里插入图片描述
下面我们将这个可执行文件的路径添加到 PATH 环境变量里。

1.2.1 设置环境变量: export

语法:export 环境变量名=添加的内容

export PATH=$PATH:目录路径

下面将当前目录的路径添加到 PATH环境变量内容中:
在这里插入图片描述
下面再将刚刚编写的可执行文件不带 ./ 进行运行:
在这里插入图片描述

切记不要在添加路径时将 PATH 环境变量写成如下情况:

export PATH=目录路径

在这里插入图片描述
运行自己的可执行文件是没有问题,但是
在这里插入图片描述

上述操作会造成 PATH 环境变量的原有目录路径都被替换成新目录的路径,想要恢复的话只能退出当前用户重新登录

因此 PATH 环境变量的作用是:当用户要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还会到PATH环境变量中指定的路径去找。通过正确设置PATH环境变量,用户可以更方便地运行程序,而不必每次都输入完整的程序路径

当然系统中不仅仅只有一个 PATH 环境变量,还存在很多不同功能的环境变量。

例如:USER环境变量

1.3 USER 环境变量

在这里插入图片描述
当一个用户登录时,USER环境变量就会记录下当前机器登录的用户。

不同用户登录Linux时,USER环境变量指向的内容都会不一样。

下面以root身份进行登录,再来查看 USER环境变量:

在这里插入图片描述

在Linux中,创建的文件都是有不同属性和权限。操作系统为了区分哪些文件可以被哪些用户进行读写,就是通过USER环境变量来控制的。

2.环境变量的组织形式(表)

  • 诸多的环境变量组织起来就变成了一张表,叫做 环境变量表。它是一个内存级别的一张表,每当在用户登录操作系统时,都会创建一张属于当前用户的环境变量表

内存级别表示:这张表不是在磁盘中进行维护,当用户登录操作系统时,环境变量表会在内存中创建。当用户退出登录或是重新登录时,这张表就会被重新刷新初始化。

环境变量对应的数据存储在系统对应的配置文件中,配置文件的位置在当前用户家目录下:
在这里插入图片描述

用vim打开

在这里插入图片描述
在这里插入图片描述

可以看.bash_profile 和 .bashrc 这两个文件其实就是两个 shell 脚本,当用户登录成功后就会按照这些配置文件对环境变量进行配置。进而形成一张内存级别的表

这个表是一个字符指针数组,数组种的每个元素都是指向一个以 \0 结尾的环境字符串

环境变量表实际上是指每个进程所持有的环境变量集合的抽象表示(记住这句话,后面会提到)。表中的每个条目都是形如key--val的键值对。

下面来查看一下环境变量表长什么样:

2.1 env 命令查看所有的环境变量

在Linux中 shell 是一个命令行解释器,它是一个进程,对应的它有属于他的一张环境变量表。

在终端输入命令 :env 可以查看对应的环境变量表

env 

在这里插入图片描述
输出的内容很多,但是可以看到几个熟悉的字眼,例如:USER、PATH、HOME。

可以看到一些规律,每一个条目中都有 大写字母 = 环境变量对应的内容,就是上面所说的键值对。

每一个大写字母单词代表就是一个环境变量,等号右边就是对应环境变量的有用的信息

除了用命令方式查看,也可以利用代码的方式来查看环境变量表。

2.2 用代码的方式查看环境变量

开始前,重新认识一下 main 函数:

main 函数是我们自己写的代码运行时的入口,这个是基于我们平时的认知。

但从现在开始就要用另一种方式去看待 main函数。

main 函数是一个函数,是一个函数那么就可以被传参,是函数就是可以被调用。

那么问题来了 main 函数是被谁调用的呢?当然是 bash !为什么这么说?

在命令行中运行一个程序的过程就是创建进程,使用./操作其实就是 shell 调用这个程序的 main 函数的过程。

在调用 main 函数时,shell 会将环境变量表传给main函数。

你没有看错,在main函数中是可以传参的。main函数不仅可以传参,而且参数有三个之多。

main 函数中可以传入三个参数分别是:int argc char* argv[ ]char* envp[ ]

提示:这里先介绍main函数的最后一个参数 envp ,该篇博客后续内容会介绍前面两个参数的作用。

参数 char* envp[] 作用是用来接收环境变量表的

2.2.1 利用 char* envp[ ] 参数查看环境变量

  • main 函数的第三个参数的类型为:字符指针数组,数组内的每一个指针都是指向对应的不同的环境变量的地址

前面提到过:环境变量表实质上就是一个字符指针数组,在这里有所不同的是数组的最后一个元素为NULL。

因此我们可以用代码的方式将环境变量输出:

在这里插入图片描述

字符指针数组中的最后一个元素为空,那么就可以将 NULL值设置为结束的条件,下面看看运行结果:

在这里插入图片描述
数组中的每一个元素都是一个字符指针,打印结果就是一个环境变量字符串。

查看环境变量的方法还有两种,接着往下看:

2.2.2 利用全局变量查看环境变量

在C语言中有那么一个全局变量也可以用来查看环境变量:

char** environ;

它是一个二级指针,可以存储一个char* 类型的地址,前面说到环境变量本质就是一张表,表中存储的是不同环境变量的字符串首元素地址,而这个全局变量就是指向环境变量表的首地址。通过这个全局变量就可以将环境变量表中的元素都打印出来。

使用这个全局变量时需要包含一个头文件:#include <unistd.h>,当然也需要进行 extern 声明一下,毕竟是在库中。

在这里插入图片描述
打印结果如下:
在这里插入图片描述
上面两个方法,不是使用参数,就是使用全局变量,很麻烦。有没有一种便捷方式去访问呢?

当然有,下面是第三种方式:

2.2.3 调用函数的方式去查看环境变量

这个函数为:

char* getenv(const char* name);

使用这个函数前也是需要包含头文件的,这个头文件为:#include <stdlib.h>

将需要用到的环境变量名称传递给 getenv 函数,该函数拿到参数后就会在环境变量表中依次对比。

如果查到对应的环境变量存在,会返回对应环境变量的首元素地址;否则会返回NULL。

在这里插入图片描述

在这里插入图片描述
通过函数调用环境变量是最常用的方式,按照用户的需求去调用需要用到的环境变量。

到这里环境变量是什么?有什么用?怎么调用?都解决了。

但是还有一个问题没有解决,那就是为什么说环境变量表在每个进程中都持有?

3. shell 中的变量

在讲 main 的时候提到过,是 shell 将环境变量表传递给main函数的。

shell 是命令行解释器,可以说 shell 本身就是程序,在Linux中的任何操作都绕不过它。命令也是程序,例如命令:ls、pwd、cat、mkdir… 。使用这些命令的时候,对应都是在 shell 进程中创建子进程的过程。

是程序就是可以创建变量,在 shell 中可以创建属于自己命名的内部变量甚至是环境变量

举个例子,创建一个简单的变量:

在这里插入图片描述
注意:查看变量内容时加上$符号

在 shell 中创建环境变量,在创建普通变量方法上再加上 export命令就能将这个变量变成环境变量:

在这里插入图片描述

再来查看一下环境变量表:
在这里插入图片描述

讲环境变量表的时候说过,环境变量这个表就是一张内存级别的表。当用户登录时OS会按照对应的配置文件内容,在shell中创建属于这个用户的环境变量表。

我们往 shell 创建普通变量时,这个过程就好比在shell内部中 malloc 一段字符空间,然后去存储这个变量的内容。

往shell 创建一个环境变量,这个操作就是在shell中创建普通变量的过程上,再向 shell 中的环境变量表再添加一个字符指针,让表中的指针的去指向这个变量的内容。

在 shell 中执行命令或是可执行文件时,即是在shell 中创建子进程,shell 会把环境变量表传递给子进程,这也是为什么 main函数的参数可以访问到环境变量的原因。

4. main函数参数的作用

调用环境变量说过 main 函数的 char* envp[ ] 参数的作用,这里主要来介绍 main 函数的另外两个参数的作用。

main 函数前两个参数如下:

int main(int argc, char* argv[]);
  • char* argv[] 是一个字符指针数组,第一个元素是当前程序的名称,其他元素用于存储传递给程序的命令行参数
  • int argc 表示传递给main函数的命令行参数的数量,argc 的值至少为1,表示程序的名称

往 shell 输入命令时,首先是命令的名称,如果要让命令实现不同功能就加上不同的选项。

将命令和命令选项输入到 shell 命令行解释器,shell 会将当前命令进行统计分析。

例如在shell中输入:ls -a -l

shell 会将 ls 命令名称的信息存储到 argv[0];而 -a、-l 选项会依次存储放到字符指针数组的 argv[1]、 argv[2]位置。
再将命令的名称、命令选项个数一个个相加起来,再存储到 argc 变量中。

shell 通过传参的方式将 argc 和 argv 传到当前程序的 main 函数中。main 函数通过这两个参数再利用条件语句,去判断用户输入了哪些命令选项,从而实现不同的功能。

下面来看看实操:

  1. 运行程序,分别打印出带选项存在 argv 数组中的储位置:

在这里插入图片描述

在这里插入图片描述

  1. 实现输入不同选项,让程序表现不同的功能

在这里插入图片描述
在这里插入图片描述

Linux 环境变量就讲到这里,感谢大家观看!

相关推荐

  1. linux设置环境变量

    2024-03-18 13:22:01       58 阅读
  2. Linux环境变量

    2024-03-18 13:22:01       61 阅读
  3. Linux 环境变量

    2024-03-18 13:22:01       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-18 13:22:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-18 13:22:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-18 13:22:01       82 阅读
  4. Python语言-面向对象

    2024-03-18 13:22:01       91 阅读

热门阅读

  1. TiDB分布式关系型数据库

    2024-03-18 13:22:01       43 阅读
  2. Vue.js动画

    2024-03-18 13:22:01       39 阅读
  3. 事务、并发、锁机制的实现

    2024-03-18 13:22:01       37 阅读
  4. 【SpringCloud微服务实战09】Elasticsearch

    2024-03-18 13:22:01       41 阅读
  5. MATLAB中的脚本和函数有什么区别?

    2024-03-18 13:22:01       41 阅读
  6. 数据库-新手笔记(聚合函数,分组)-进阶

    2024-03-18 13:22:01       42 阅读
  7. 链表实现学生管理系统

    2024-03-18 13:22:01       30 阅读
  8. rocky9.2部署kubernetes 1.29.x

    2024-03-18 13:22:01       30 阅读
  9. MySQL的备份

    2024-03-18 13:22:01       40 阅读
  10. 【QED】血压高的天依

    2024-03-18 13:22:01       42 阅读