Linux环境变量

💘作者:泠沫
💘博客主页:泠沫的博客
💘专栏:Linux系统编程,文件认识与理解…
💘觉得博主写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!
在这里插入图片描述

🏠 环境变量基本概念

  • Linux环境变量是指在操作系统中设置的具有特定含义的一些变量,它们可被各种程序和脚本调用访问。环境变量可以影响用户会话的运行方式,如控制应用程序的默认选项、设置系统语言等。

  • 如我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但
    是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。

🏠 常见环境变量

  • PATH:用于指定可执行文件的搜索路径。

  • HOME:Linux用户的主目录,通常是/home/用户名。

  • USER:当前登录用户的用户名。

  • SHELL:当前用户使用的shell类型(比如bash、zsh等)。

  • LANG:指定系统默认语言和字符集,影响应用程序的输出和显示方式。

  • TEMP、TMP:指定临时文件存储位置。

  • PS1、PS2:控制终端提示符的样式。

  • DISPLAY:用于指定X11服务器的地址,只有在使用图形界面应用程序时才需要设置。

  • EDITOR:指定默认的文本编辑器,例如vim、nano等。

  • LD_LIBRARY_PATH:用于指定动态链接库的搜索路径,当应用程序调用共享库时会自动在此路径下寻找相关的库文件。

🏠 环境变量类型

  • 全局环境变量:全局环境变量是对整个系统生效的环境变量,它们可以被所有用户和应用程序访问。一般情况下,全局环境变量被保存在/etc/profile文件或/etc/environment文件中。全局环境变量的设置将影响到整个系统,在启动终端会话时就会进行加载,并覆盖用户自定义的同名环境变量。

  • 局部环境变量:局部环境变量只对当前用户或当前shell生效。当在bash shell脚本中定义和使用变量时,这些变量默认是局部变量。

  • 如果想使局部变量变成环境变量(即全局变量),可以使用"export"命令将其导出至环境变量表中。例如,输入"export MY_VAR=hello",则"MY_VAR"就从局部环境变量转换成了全局环境变量。 与此相对的,unset命令也可以用来清除环境变量。

  • 无论是全局环境变量还是局部环境变量,均只在本次登录shell时有效,一旦重新登陆,环境变量会重修变成初始默认值。

🏠 查看环境变量方式

  • printenv命令:该命令可以列出当前用户的所有环境变量及其取值。在终端上输入"printenv"即可执行该命令。

  • echo命令:该命令可以打印出单个变量(包括环境变量和局部变量)的取值。例如,要查看PATH环境变量,可以在终端上输入"echo $PATH"。

  • env命令:该命令可以列出所有环境变量及其取值,类似于"printenv"命令。在终端上输入"env"即可执行该命令。

  • set命令:该命令可以列出shell会话中的所有变量(包括环境变量和局部变量)及其取值。在终端上输入"set"即可执行该命令。

🏠 环境变量的全局属性

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

int main()
{
    char* mypwd = getenv("USER");
    if(!strcmp(mypwd,"root"))
    {
        cout << "run succeed..." << endl;
    }
    else
    {
        cout << "-bash: ./pro : Permission denied" << endl;
    }
    return 0;
}

在这里插入图片描述

  1. 我们运行自己的可执行程序,该可执行程序就变成了一个进程,它的父进程就是bash。也就是说,我们执行的可执行程序是bash的一个子进程,但是我们发现该子进程在运行过程中,居然可以访问系统内环境变量。这说明,环境变量具有全局属性,可以被子进程继承下去,这可以用来应对不同的场景。

  2. 所以,有的时候我们执行某些指令的时候,为什么系统会报错Permission denied。就是因为有一个环境变量是USER,我们所敲的指令本质上也是一个一个的可执行程序,然后加载到内存中成为了bash的子进程。在那些指令内部,必然判断了我们是否为root,如果不是则不允许执行该指令,程序直接终止退出。试想如果环境变量没有全局属性,子进程无法继承环境变量,那么该功能也就无法实现。

子进程获得环境变量的三种方式

  1. getenv()函数
  2. main()函数的函数参数传递
  3. 系统有一个全局的环境变量表指针char ** environ

🏠 环境变量组织方式

在这里插入图片描述
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串。

🏠 main函数的参数–命令行参数

一般情况下,我们大家在main函数的时候都是:int main(),参数一般都为空。

但实际上main函数也是有参数的:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int main(int argc, char* argv[], char* env[])
{
    for(int i = 0; env[i]; i++)
    {
        printf("env[%d]:%s\n", i, env[i]);
    }
    cout << endl;
    for(int i = 0; i < argc; i++)
    {
        printf("argv[%d]:%s\n", i, argv[i]);
    }
    if(!strcmp(argv[1],"-a"))
        printf("执行功能a\n");
    if(!strcmp(argv[1],"-b"))
        printf("执行功能b\n");
    if(!strcmp(argv[1],"-c"))
        printf("执行功能c\n");
    if(!strcmp(argv[1],"-ab"))
        printf("执行功能ab\n");
    if(!strcmp(argv[1],"-ac"))
        printf("执行功能ac\n");
    if(!strcmp(argv[1],"-bc"))
        printf("执行功能bc\n");
    if(!strcmp(argv[1],"-abc"))
        printf("执行功能abc\n");
    return 0;
}

在这里插入图片描述

由此可见,main函数其实也可以传参数。只是一般情况下我们不需要给该程序带上特定的选项,且不用命令行的方式执行程序,所以才一般不传入参数。

对于main函数的三个参数:

  1. argc表示的是指令该可执行程序命令行的指令个数,也就是第二个指针数组的大小。

  2. argv表示执行该可执行程序的指令字符串,以空格作为字符串的分割。

  3. env表示环境表指针,指向存放环境变量的数组的首元素。该方式可以让子进程继承bash的环境变量。

其实就算不传递第三个参数,子进程也可以拿到bash的环境变量,一种方式是调用getenv函数来获得,而另一种方式则是C语言提供了一个全局变量environ,该变量是一个二级指针,指向env环境表指针。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;

int main()
{
    extern char** environ; 
    for(int i = 0; environ[i]; i++)
    {
        printf("%d:%s\n", i, environ[i]);
    }
    return 0;
}

在这里插入图片描述

该方式执行结果与传入参数char* env[]一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值