• 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:目录路径
    
    • 1

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

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

    export PATH=目录路径
    
    • 1

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

    上述操作会造成 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 
    
    • 1

    在这里插入图片描述
    输出的内容很多,但是可以看到几个熟悉的字眼,例如: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;
    
    • 1

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

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

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

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

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

    这个函数为:

    char* getenv(const char* name);
    
    • 1

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

    将需要用到的环境变量名称传递给 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[]);
    
    • 1
    • 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 环境变量就讲到这里,感谢大家观看!

  • 相关阅读:
    鸿蒙系统的开发与学习:一、安装工具与处理报错
    wife_wife【web 攻防世界】
    Keil软件仿真的方法: μVision2调试器
    Sql Server 2017主从配置之:事务日志传送
    AC自动机
    设计模式之模板方法模式
    mysql 操作命令
    从零开始的stable diffusion
    Java中String对象的replaceAll方法调用性能优化小技巧
    Android挂载系统分区执行mount和remount
  • 原文地址:https://blog.csdn.net/weixin_57663528/article/details/136638724