• 【Linux】环境变量



    一、初步看一看环境变量

    对于系统内存级的指令,比如ls,cd,which,clear等指令,这些指令其实都是一个个进程,直接输入即可运行起来,可是我们自己写的程序想要运行不同,一般我们编译好的可执行程序,需要在程序名前面加上一个./,来让程序跑起来。

    这里有问题了,为什么系统的指令不需要./就能跑起来呢?

    先来看一看系统的环境变量:
    在这里插入图片描述

    输入echo $PATH,$是dollar符号,英文的环境下按shift+4即可打出来。

    输出结果就是系统内部的环境变量。
    注意:你可以看到,不同的路径之间是用冒号分隔开的。

    我们输入的一些命令,比如比如ls,cd,which,clear等指令,系统会通过配置好的这个环境变量,来直接找到该命令所在路径,并直接运行起来。

    我们也可以自己加上自己的路径,让我们自己写的可执行程序可以直接像指令一样跑起来。

    通过这条指令后:

    这样:PATH=$PATH:/home/dzt/learning/10_22_priority

    注意:PAHT=是赋值的意思,给PATH赋值,$PATH:就意味着在原有的环境变量的基础上加上我自己路径的环境变量。
    如果直接让PATH=自己的路径,会将原来的系统的环境变量覆盖掉。

    在这里插入图片描述

    这样就大功告成了。

    此时执行自己的可执行程序,就可以直接敲程序名就能运行,不需要再./程序名了,当然,./程序名一样可以通过。

    如果不小心覆盖了系统的环境变量,可以退出xhell重新登陆即可。

    其次,可以通过env指令来获取各种环境变量。

    在这里插入图片描述

    二、什么是环境变量

    举个简单的例子说明:

    先看下面一段代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 
      5 int main()
      6 {
      7     char who[32];
      8     strcpy(who,getenv("USER"));
      9 
     10     if(strcmp(who, "root") == 0)
     11     {
     12         printf("你是root用户,你可以做任何事情\n");
     13     }
     14 
     15     else
     16     {
     17         printf("你是普通用户,你受权限约束\n");                 
     18     }
     19 
     20     return 0;
     21 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    getenv函数是获取对应字符串的环境变量,比如上文,通过getenv(“USER”),获取到当前USER的环境变量,从而判断当前用户是谁。

    当我在普通用户和root用户的环境下分别运行此代码时,结果如下:

    在这里插入图片描述
    为什么操作系统能识别到当前用户到底是谁,怎么做到的呢?

    其实这就得益于getenv系统调用,来获取当前用户的环境变量,进而判断该用户是谁!

    所以环境变量概念的初步解释:

    环境变量是一组name = value形式的变量,不同的环境变量有不同的属性,通常具有全局属性

    命令行参数

    为了更好理解环境变量,下面引出命令行参数的概念。

    在main函数中,也是可以带参数的。

    int main(int argc,char* argv[]);
    
    • 1

    main函数的两个参数,就是命令行参数。

      6 int main(int argc,char* argv[])
      7 {
      8     int i = 0;
      9     for(i = 0;i<argc;i++)                                                                                                               
     10     {
     11         printf("argv[%d]->%s\n",i,argv[i]);
     12     }
     13 
     14 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们通过打印出main函数的参数,看看会发生什么。
    在这里插入图片描述
    执行了该程序后,可以发现:

    argv数组存储的,都是我们输入的命令行!

    在这里插入图片描述

    实际上,bash命令行解释器会将 ./test -a -b -c -d -e这个字符串按照空格分隔开,每一个字符串就是一个命令行参数存放到argv[]数组中,而argc就是数组的元素个数。

    那为什么main函数要这样设计呢?

    为指令,工具,选项,等提供命令行选项的支持!!

    可以看到,我们日常执行的ls,ls -a,ls -a -l等等,这些命令后面有些可以带参数,也可以不带参数。

    正因为命令行具备选项等,所以main才要这样设计,来接收参数。

    其实,main函数不止有两个参数,还有第三个参数:char* env[]
    在这里插入图片描述

    也就是说,还能通过main函数打印出环境变量出来。
    在这里插入图片描述

    结论:我们所运行的进程,都是子进程,bash进程本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我的环境变量!

    因为子进程能够继承父进程的环境变量,所以在每个进程中都能读取到环境变量信息,这也就解释了为什么环境变量具有全局性!

    如何证明子进程会继承父进程的环境变量?

    我们就自己写一个环境变量, 看看子进程是否可以继承。

    export MY_VALUE=12345678
    
    • 1

    通过export,将MY_VALUE这个自己写的环境变量导入,再打印出来,即可看到我们自己的环境变量:

    在这里插入图片描述

    此时,运行main函数,也能看到这个我们自己写的环境变量,就证实了环境变量可以被子进程继承,具有全局属性!

    自己写的环境变量可以取消掉:

    unset MY_VALUE
    
    • 1

    此时就看不到自己写的环境变量在系统中了。

    本地变量和内建命令

    本地变量:只在bash内部有效,不会被子进程继承下来的变量。

    在这里插入图片描述
    这些就是本地变量。

    本地变量只在bash进程内部使用,不会被子进程继承下来。

    单纯设置本地变量,并不会被子进程继承下来,如果想要让子进程继承下来,还得将本地变量导入到环境变量中,方法还是使用export

    如何查到bash进程中的所有环境变量?

    使用set命令

    在这里插入图片描述

    此时就看到我们刚刚设置的几个本地变量a,b,c,这些所有的变量中,如果不是本地变量, 那就是全局变量。

    在这里插入图片描述

    ps1就是对应下面的命令行待输入时的格式。

    对于ps2,

    在这里插入图片描述
    输入ls \后,意思就是指令可以换行继续输入,就像c语言一样,代码可以换行继续输入。而那个>符号就是本地变量PS2。

    所以,本地变量仍然有存在的意义,提供给bash内部使用。

    内建命令

    Linux中有两批命令:

    • 1.常规命令——创建子进程完成
    • 2.内建命令——bash不创建子进程,而是由自己亲自执行,类似于bash调用了自己写的,或者系统写的函数。
     7 int main(int argc, char* argv[], char* env[])
        8 {
        9     sleep(30);
       10     printf("change begin\n");                                 
       11     if(argc == 2)
       12     {
       13         chdir(argv[1]);
       14     }
       15 
       16     printf("change end\n");
       17     sleep(30);
       18}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    bash是能够自己改变自己的进程的路径的。

    通过调用自己的chdir函数。

    在这里插入图片描述

    所以对于内建命令来说:比如cd命令

    如果匹配到cd命令,他就会大概执行下面的操作:

    if(strcmp(argv[1],"cd") == 0)
    {
        chdir(argv[1]);
    }
    
    • 1
    • 2
    • 3
    • 4

    就不让我创建子进程。

    这就是内建命令的功能。



    总结

    初学环境变量,非常抽象,难以理解。

  • 相关阅读:
    ESP8266-Arduino编程实例-ULN2003步进电机驱动
    数学建模学习(92):Jaya 算法对定位问题进行寻优
    开学季&河科大社区活动详情介绍实例
    backup (攻防世界)
    新鲜出炉!ECCV2022 107个开源数据集合辑,全球 AI 研究热点一网打尽
    React 学习笔记:JSX 语法
    ROC 曲线介绍以及 python 画法
    数据结构--线性表
    新库上线 | CnOpenData信息传输、软件和信息技术服务业工商注册企业基本信息数据
    常用软件学习
  • 原文地址:https://blog.csdn.net/w2915w/article/details/134013206