欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > 深入了解Linux系统—— 环境变量

深入了解Linux系统—— 环境变量

2025/5/5 10:52:59 来源:https://blog.csdn.net/LH__1314/article/details/147693729  浏览:    关键词:深入了解Linux系统—— 环境变量

命令行参数

我们知道,我们使用的指令它本质上也是一个程序,我们要执行这个指令,输入指令名然后回车即可执行;但是对于指令带选项,又是如何实现的呢?

问题:main函数有没有参数?

在我们之前写代码的时候,我们知道main函数是程序的入口;但是操作系统在执行程序之前,会先执行一个入口函数(_start),然后由这个入口函数去调用我们的main函数。

那我们的main函数到底有没有参数?答案是有的。

我们先来看下面运行程序的现象:

#include <stdio.h>
int main(int argc, char* argv[])
{for(int i = 0;i<argc;i++){printf("argv[%d] : %s\n",i,argv[i]);}return 0;
}

在这里插入图片描述

这里,我们在命令行中打开某个可执行程序,后面跟上选项(指令 -选项);

可以看到在main函数中我们是可以访问命令行输入的内容的(命令行参数)。

main函数的参数都有哪些内容呢?

  • argc:命令行参数的个数
  • argv:命令行参数的内容(char*类型的数组,最后以NULL结尾)
  • env:环境变量表(在文章后面内容中详细讲解)。

在这里有一个疑问,我们在命令行输入的内容是如何转化成argv表,并传递给main函数的呢?

这个就比较简单了,我们在命令行中输入的内容,由我们的命令行解释器bash对这些内容进行拆分,然后形成命令行参数表(argv)和参数的个数argc

然后再通过调用等一系列操作(bash创建子进程,通过execve系统调用)将参数传递给main函数。

简单来说,就是命令行解释器(bash)对我们命令行内容进行拆分,然后形成命令行参数个数argc和命令行参数列表argv

在这里插入图片描述

所以,有了命令行参数列表,我们程序就可以实现不同的子功能(命令 + 选项的实现原理)

环境变量

在了解环境变量之前,先思考一个问题,为什么在执行我们自己写的程序时就要带路径,而使用指令程序时就不用带路径?

我们想要运行一个程序,首先要先找到这个程序(bash去找)

这个问题就很简单了,我们的指令程序都在/usr/bin目录下,而我们的程序不在usr/bin目录下。

但是,为什么在usr/bin路径下的程序,在执行时不需要带路径?

  • 环境变量一般指操作系统中用来指定操作系统运行环境的一些参数。
  • 例如:我们在写的C/C++代码,在链接的时候,我们不知道所链接的动静态库在哪里,但是依然可以链接成功生成可执行程序,其原因就是:有关环境变量帮助编译器进行查找
  • 环境变量通常具有某些特殊用途,在操作系统中通常具有全局性

查看环境变量

  • 查看所有环境变量:env
  • 查看一个环境变量:ench $环境变量名

在这里插入图片描述

设置环境变量

export

我们现在能够看到环境变量了,我们可不可以修改环境变量?当然是可以的

export新增环境变量

我们可以使用export指令来新增一个新的环境变量,具体语法如下:

export name=val

在这里插入图片描述

export除了新增一个环境变量,我们还可以使用它来修改一个已经存在的环境变量的值。

在这里插入图片描述

这里如果进行了上述修改,我们的大部分指令都无法使用了,因为在当前PATH路径下,bash找不到可执行程序。

但是存在一些还可以使用的指令,因为这些指令是bash进程自己执行的,比如export

在本篇文章后序内容详细叙述

unset

我们可以新增一个环境变量,那我们可不可以删除一个环境变量?当然也是可以的

unset指令可以删除一个环境变量,用法如下:

unset name

在这里插入图片描述

常见的环境变量

PATH

PATH环境变量,它指的是命令的搜索路径;

为什么在usr/bin路径下的程序,在执行时不需要带路径?

我们要运行一个程序,首先要找到它,所以我们自己写的程序运行时需要带路径;

而在usr/bin路径下的指令程序不需要带路径,这是因为存在环境变量PATH帮助bash去查找执行程序。

在这里插入图片描述

所以,当我们把我们自己写的程序所在的路径加入到PATH中,或者将我们的可执行程序放到/usr/bin目录下,我们运行我们自己写的程序就也不需要带路径了。

这里就不演示了,感兴趣的可以去尝试一下

HOME

Linux中,当我们执行cd ~指令时,我们会进入当前用户的家目录;但是,操作系统是如何知道我们当前用户的家目录呢?

这里就直接说了:存在一个环境变量HOME;当我们执行cd ~时,bash就会在环境变量表中查找HOME,然后进行到HOME加目录中。

在这里插入图片描述

此外,root用户的家目录和普通用户的家目录还是存在一定差别的

在这里插入图片描述

SHELL

SHELL环境变量,它表示当前的shell,也就是当前使用的命令行解释器;

一般情况下是/bin/bash

在这里插入图片描述

更多的环境变量

除了上述的环境变量,还存在非常多的环境变量,这里简单了解一下

在这里插入图片描述

  • HOSTNAME:当前系统的主机名
  • HISTSIZEbash记录历史指令的个数
  • SSH_TTY:当前通过SSH会话链接终端设备的路径
  • PWD:表示当前路径
  • USER:当前用户的登录名
  • LOGNAME:可以理解为和user一样
  • _:表示上次路径

获取环境变量

在上述中,讲述了使用envecho $查看环境变量,那我们现在想要通过写代码时获取环境变量该如何去做呢?

main函数参数

在上面叙述main函数参数时,提到main函数还存在第三个参数env,我们就可以通过这个参数来获取环境变量

#include <stdio.h>
int main(int argc, char* argv[], char* env[])
{int i = 0;for(;env[i]!=NULL;i++){printf("env[%d] : %s\n",i,env[i]);}return 0;
}

在这里插入图片描述

系统调用

main函数第三个参数env它是环境变量参数表,我们查看起来不是很方便;

我们可以通过系统调用来在代码中获取环境变量的值:

getenv

在这里插入图片描述

getenv,我们把要查看环境变量的名字传参给getenv函数,它会返回我们查询环境变量的值。

#include<stdio.h>
#include<stdlib.h>
int main()
{printf("%s\n",getenv("PATH"));return 0;
}

在这里插入图片描述

putenv对于这个函数,这里就先不叙述,在后序文章中再详细讲解。

通过第三方变量获取

libc在定义着一个全局变量environ,它始终指向当前的环境变量表;

它不存在于任何头文件,我们在使用它时,需要使用extern声明。

#include<stdio.h>
int main(int argc, char* argv[])
{extern char** environ;int i = 0;for(;environ[i]!=NULL;i++){printf("environ[%d] : %s\n",i,environ[i]);}
}

在这里插入图片描述

执行程序,我们可以发现依然可以获取全部的环境变量。

此外,父进程的环境变量可以被子进程继承;就比如父进程bash创建我们的子进程时,

理解环境变量

要理解环境变量,这里我们先思考一个问题,环境变量存储在哪里?

在执行一个程序时,首先要找到到这一个程序,那谁去找呢?

答案是bash去找,通过环境变量PATH去找,在bash中存储着一份环境变量表;

现在又存在一个问题,当我们修改环境变量以后,退出登录,再次登录时我们会发现环境变量又变为修改前的值了。

所以环境变量最开始是存储在哪里呢?

答案:在系统的配置文件中

那我们现在是不是就可以这样去理解了:在我们每次登录时,操作系统为我们创建一个bash,再将环境变量表拷贝一份到bash中;这样我们每次登录bash中都存在一份环境变量表。

环境变量特性

  • 环境变量通常具有全局属性,可以被子进程继承下去。

环境变量表

在上诉代码中,我们无论是使用main函数参数env还是全局指针变量environ进行访问全局变量是时,循环条件写的都是env[i]!=NULL/environ[i]!=NULL

这是因为,环境变量表它本质上就是一个指针数组,数组最后以NULL结尾。

在这里插入图片描述

补充

本地变量

在操作系统中除了环境变量之外,还存在着本地变量;

就比如我们在命令行直接输入i=1,这样我们使用env查看环境变量时是查看不到i的;但是我们可以使用echo $i来查看变量i的值。

在这里插入图片描述

env是查看所有的环境变量,而如果我们想要查看所有的本地变量,就要使用set,它能显示出所有的环境变量和本地变量;当然我们也可以使用echo $查看某一个变量的值。

这里可能感觉怪怪的,为什么要存在本地变量呢?

  1. 作用域限制
    本地变量仅在当前Shell会话或函数内部有效,不会传递给子进程或其他Shell环境。这种隔离性避免了变量被意外修改或污染其他进程的运行环境。
  2. 临时数据存储
    适用于临时存储中间计算结果或循环控制变量(如计数器),用完即弃,无需长期保留,简化资源管理。
  3. 安全性增强
    若变量包含敏感信息(如临时密钥),使用本地变量可防止其被子进程继承,降低数据泄露风险。
  4. 避免命名冲突
    在脚本或函数中使用本地变量(如通过local关键字声明),能隔离同名变量的影响,提升代码的模块化和可维护性。

以博主现在的认知,简单理解就是为了满足bash的语法

内建命令

这个问题在上面简单描述了,我们的环境变量是存在于bash中的,因为我们所有执行的程序都是bash去执行的,bash需要这些环境变量来完成执行我们的程序;

在修改PATH时,我们发现一个问题,将PATH修改之后,一部分指令不能执行了,但是一部分指令是可以执行的,这是为什么呢?

这里简单解释一下:

我们可以将指令分为两部分:

  • 普通命令:bash通过创建子进程,然后让子进程去执行;
  • 内建命令:bash自己通过函数调用或者系统调用去完成,不需要创建子进程。

这里内建命令像export就是bash自己直接去完成的,我们就是修改了PATH对它是没有影响的,所以它可以执行;

到这里本篇文章内容大致就结束了,感谢支持

简单总结:

  1. 了解命令行参数,理解main函数是三个参数
  2. 环境变量,查看env/echo、设置环境变量export
  3. 了解常见的环境变量
  4. 通过main函数参数、系统调用、environ获取环境变量
  5. 理解环境变量具有全局性、环境变量表的结构
  6. 简单了解本地变量和内建命令

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词