Linux-环境变量

文章目录

    • 常见环境变量
      • 查一个环境变量
      • 系统调用接口getenv
    • 什么是环境变量?
      • 命令行参数
      • 向量表
      • 两张核心向量表
    • 结论
      • 证明一下子进程继承了父进程的环境变量?
        • export将本地变量变成环境变量
    • 本地变量&&内建命令
      • 本地变量:只会在本BASH内部有效,不会被继承
      • 内建命令
    • 总结
      • 和环境变量相关的命令
      • 通过代码如何获取环境变量的其他方式

常见环境变量

Linux-环境变量_第1张图片

查一个环境变量

echo需要加上$符号才能打印出来环境变量

系统调用接口getenv

char *getenv(const char *name);
在代码中获取一个环境变量

  1. PATH:Linux系统的指令搜索路径

bash怎么知道指令在哪里?
bash内部维护了PATH环境变量(指令的搜索路径)

which 是如何找到指令路径的?
对PATH进行搜索

修改PATH
在这里插入图片描述

PATH=/home/ljh  //将PATH修改成只有/home/ljh,大部分指令无法使用

$PATH是内存级的环境变量,修改后重新登陆即可恢复

  1. SHELL
    用的哪一个SHELL,shell有bash等。。
  2. USER
    当前用户是?

有没有权限得先知道你是谁,对权限理解进一步加深,不同用户根据环境变量不同受限制不同
Linux-环境变量_第2张图片

  1. HOME
    家目录

什么是环境变量?

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

命令行参数

int main(int argc,char* argv[])//指针数组,存的是char*,字符串
{}

c = count 个数
v = value
数组里有多少个元素
我们之前学的main函数从来没有参数,那这两个参数是什么呢?管他是啥我先打印出来看看

  int i = 0;
  for(; i<argc ;i++)
 {
    printf("argv[%d]->%s\n",i,argv[i]);
 }

结果
打印出来这不是命令行参数吗?
Linux-环境变量_第3张图片
为什么要这么干?
为指令、工具,软件等提供命令行选项的支持!!
例如ls -l 的实现

		// if(argc != 2)
   43    // {
   44    //     printf("Usage: %s -[a|b|c|d]\n",argv[0]);
   45    //     return 0;
   46    // }
   47    // 
   48    // if(strcmp(argv[1],"--help") == 0)
   49    // {                                                                                                                            
   50    //     printf("Usage: %s -[a|b|c|d]\n",argv[0]);
   51 
   52    // }else if(strcmp(argv[1],"-a") == 0)
   53    // {
   54    //     printf("功能1\n");
   55    // }else if(strcmp(argv[1],"-b") == 0)
   56    // {       
   57    //     printf("功能2\n");
   58    // }else if(strcmp(argv[1],"-c") == 0)
   59    // {
   60    //     printf("功能3\n");
   61    // }else if(strcmp(argv[1],"-d") == 0)
   62    // {
   63    //     printf("功能4\n");
   64    // }else 
   65    // {
   66    //     printf("default\n");
   67    // }

向量表

main函数被Linux-环境变量_第4张图片调用
你以为你写的./mycmd -a -b -c,其实输入的是字符串"./mycmd -a -b -c",然后以空格为分隔符打散放入的argv[ ]数组中,有几个字符串argc就是几,然后传入给main函数。
并且argv数组 最后一个位置是NULL
所以还可以不用argc遍历,直接利用最后一个是NULL来遍历

 int i = 0;
 for(; argv[i] ;i++)
 {
  	printf("argv[%d]->%s\n",i,argv[i]); //命令行参数表
 }

Linux-环境变量_第5张图片
那这个命令行参数和环境变量有什么关系呢?
还真有点关系,因为main函数还有第三个变量env

int main(int argc,char* argv[],char* env[])
{
}

char* env[](环境变量表)和命令行参数表结构一摸一样
Linux-环境变量_第6张图片
那就打印出来看看

	   int i = 0;
       for(; env[i] ;i++)
       {
          printf("env[%d]->%s\n",i,env[i]);    //环境变量表
       }
             

结果
打印出来了环境变量

两张核心向量表

  1. 命令行参数表
  2. 环境变量表

不要以为一个进程启动就是把程序加载到内存,而是当我们自己的程序变成进程再启动时,一定有人调用main函数,给main函数把这两张表传入

结论

环境变量概念中的具有全局属性是什么意思?
我们所运行的进程,都是子进程,bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我的环境变量!

证明一下子进程继承了父进程的环境变量?

思路:自己增加一个环境变量,子进程如果会继承就会被看到

export将本地变量变成环境变量

MY_VAL=123456//本地变量
export MY_VAL=123456//导出环境变量

同样打印环境变量表

       int i = 0;
       for(; env[i] ;i++)
       {
           printf("env[%d]->%s\n",i,env[i]);    //环境变量表
       }
             

在这里插入图片描述
Linux-环境变量_第7张图片
bash里面有自己定义的MY_VALUE,自己的mycmd子进程也查到了,验证完成。


子进程要修改环境变量不能影响父进程的环境变量,要发生写时拷贝

以前main函数从来没传入env,那么子进程是如何继承的?
第1种直接传入
第2种继承方式,到地址空间再谈

本地变量&&内建命令

本地变量:只会在本BASH内部有效,不会被继承

什么时候我的进程需要本地变量呢?
比如ps1搞出了命令行的格式 user hostname w工作目录 $
所以我们需要一些只在bash内部的符号,不要被子进程继承下去,所以有了本地变量的概念

Linux-环境变量_第8张图片

内建命令

问题:echo要不要创建子进程,如果创建,那么它无法继承bash的本地变量,但是这里却打印出来了,为什么呢?
Linux-环境变量_第9张图片
王婆(bash)说媒 如果这个媒特别难说,那么就要创建子进程,但是如果这个媒很有把握,那王婆还是愿意自己上的
所以echo是内建命令
同样cd 也是内建命令 - 系统调用chdir()
Linux-环境变量_第10张图片

		  sleep(15);
   18     printf("change begin\n");  //目录切换,内建命令cd模拟
   19     if(argc == 2)
   20     {
   21        chdir(argv[1]);
   22     }
   23     
   24     sleep(15);
   25     printf("change end\n");   

我们可以模拟cd命令,利用系统调用chdir()更改自己的工作目录,而不是创建子进程
如果我们今天自己写的mycmd是写的bash本身的话,他不给你创建子进程同样利用chdir改变工作目录cwd
在这里插入图片描述
注意
./mycmd / 更改本身的cwd
而pwd创建子进程继承了bash,bash又没改,所以还是原来的工作目录,所以只能ls /proc去看cwd
在这里插入图片描述

总结

和环境变量相关的命令

Linux-环境变量_第11张图片

不同的环境变量用途不同,所以需要具体问题具体分析

进程 环境变量 进程地址空间 三位一体 进程的概念再也不是问题

通过代码如何获取环境变量的其他方式

通过第三方变量environ获取

		int main(int argc,char* argv[])//指针数组
    7 {               
    8     extern char** environ; //C语言提供的全局变量,形参中不用再传递env环境变量表了                                                  
    9     int i = 0;  
   10     for(; environ[i] ;i++) //二级指针 指向char* 环境变量表 ,类似于形参char* env[]数组退化为指针char ** env   
   11     {  
   12         printf("%d : %s\n",i,environ[i]);  
   13     } 
   		return 0;
   	} 

你可能感兴趣的:(Linux,linux)