• Linux之环境变量



    前言

    本文介绍了Linux中的环境变量的相关概念。


    一、环境变量

    1.概念

    1. 环境变量(environment variables),一般是指在操作系统中用来指定操作系统运行环境的一些参数。环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性(类似于程序中的全局变量)。

    2.运行程序

    1. 要执行一个程序,首先要找到该程序在磁盘中的位置,那么如何去寻找该程序呢?
      当然是通过该程序的路径。

    问题来了,为什么系统命令也是程序,但是执行它们时我们不需要带上路径,而我们自己的程序需要带上路径(例如:执行当前目录下的可执行文件test,需要用./test,'.'是当前路径的意思,因此是执行当前路径的文件test)。

    1. 如果我们想让自己的程序在执行时也不需要带上路径(即,直接使用test)应该怎样做
    • 方法1:
      将要执行的文件拷贝到系统的默认路径下(系统执行命令会在默认路径下寻找)。
      命令:sudo cp 文件名 /usr/bin/
      但是,我们不推荐这种方法,因为我们自己的程序未经过测试会污染操作系统的指令池。
      这种方法之所以可以实现,是因为系统的环境变量会帮助编译器查找对应的文件。
    • 方法2:
      直接将当前路径添加到环境变量里。
      命令:export PATH=$PATH:当前路径//注意分割路径使用的时':'
      在Linux中的bash(命令行)是可以定义变量的。Xshell登录的时候,系统会将.bash_profile执行一次,将环境变量放置在当前的shell中,所以一旦启动成功系统就会在内存中维护一个环境变量$PATH

    3.windows下的环境变量

    在这里插入图片描述

    4.常见的环境变量

    PATH:指定命令的搜索路径
    在这里插入图片描述

    HOME:指定用户的主工作路径(即,用户登录到Linux系统中的默认路径,用户的家目录)
    在这里插入图片描述

    LOGNAME:当前登录的用户名
    在这里插入图片描述

    HOSTNAME:主机名
    在这里插入图片描述

    SHELL:当前Shell,它的值通常是/bin/bash
    在这里插入图片描述
    查看环境变量的方法:

    1. env(查看所有的环境变量)
      在这里插入图片描述
    2. echo $NAME(NAME用环境变量名来替换,就像上面查看的常见的环境变量一样)

    二、系统调用获取环境变量

    如果我们不想通过指令来获取环境变量,而是想在程序中获取环境变量,那么我们可以使用系统调用getenv

    1.getenv

    在这里插入图片描述
    在这里插入图片描述

    2.演示

    1.标识当前的Linux用户

    文件test1.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #define USER "USER"
      4 int main()
      5 {
      6         char* who = getenv(USER);
      7         printf("user:%s\n",who);
      8         return 0;
      9 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果
    在这里插入图片描述

    2. 判断当前用户是否为root

    文件test1.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #define USER "USER"
      5 int main()
      6 {       
      7         char* who = getenv(USER);
      8         if(strcmp(who,"root") == 0)
      9         {       
     10                 printf("user:%s\n",who);
     11         }
     12         else
     13         {       
     14                 printf("权限不足\n");
     15         }
     16         return 0;
     17 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行结果:
    在这里插入图片描述
    这就解释了如何知道当前用户是否有权限去访问某文件。
    执行指令或者访问文件时,文件(指令也是文件)上面的拥有者和所属组都会更根据当前用户的环境变量USER,去进行身份认证,判断是否拥有权限。

    三、设置环境变量

    1.关于变量的命令

    1.echo

    显示某个环境变量值
    在这里插入图片描述
    为什么用echo可以显示myval的值,但是用env不能显示该变量的值?
    因为该变量不是环境变量而是本地变量,因此,图中的方式不是正确设置环境变量的方式。正确的方式应该使用export

    2.export

    设置一个新的环境变量
    在这里插入图片描述

    3.env

    显示所有环境变量
    也可以用grep 命令,筛选出我们想看到的环境变量,如果没有就什么也不显示

    4.unset

    清除环境变量
    在这里插入图片描述

    5.set

    显示本地定义的shell变量(本地变量,类似于程序中的局部变量)和环境变量
    在这里插入图片描述

    2.子进程继承

    bash是一个系统进程,而在命令行上运行./mycmd时,mycmd会变成bash的子进程。环境变量具有全局属性的根本原因是它是定义在bash中的,而父进程的全局变量会被子进程共享(即,会被子进程继承下去)。本地变量是定义在进程中的局部变量,只在当前进程(bash)中有效。
    为什么子进程要继承父进程的环境变量?
    答:为了不同的应用场景,例如:上面用USER实现的身份认证,有的进程需要用到这些环境变量来完成对应的任务。

    3.PWD

    1. 概念

    显示当前路径
    系统是如何得知我当前的路径在哪里?
    例如:操作系统的基础指令ls,加上文件名就可以查看文件,不用加上对应的路径,那么系统是如何得知我当前的路径呢?——PWD
    该环境变量在bash中维护当前所处路径。路径发生改变时,shell会调整环境便利的值,而运行ls时在创建子进程,环境变量会被子进程继承,所以ls拿到了当前路径,因此使用ls时不需要带上当前路径。

    2.实现PWD

    文件test2.c

      1 #include<stdio.h>
      2 #include<unistd.h>
      3 #include<stdlib.h>
      4 int main()
      5 {
      6         printf("%s\n",getenv("PWD"));
      7         return 0;
      8 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果:
    在这里插入图片描述

    四、命令行参数

    main函数也是有参数的:argc(命令行参数的个数)、argv[](命令行参数表)、env[](环境变量表)。
    main函数也是被系统进行调用的,它的参数是由系统进行传参的。

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

    运行:
    在这里插入图片描述
    可以看到我们在命令行输入的参数越多,数组argv的内容也就越多。
    命令行参数实际上是将程序名(文件名)和选项(-a/-b/-c等)传递给argv(指针数组,argv[0]存储的是程序名,剩下的存储的是选项),而argc表示选项的个数
    命令行参数的意义在于通过不同的选项控制不同的结果。
    例子:
    文件test2.c

      1 #include<stdio.h>
      2 int main(int argc , char* argv[])
      3 {
      4         int i = 0;
      5         if(argc != 2)
      6         {
      7                 printf("Usage:\n\t%s [-a/-b/-c/-ab/-ac/-bc/-abc]\n",argv[0]);
      8         }
      9         if(strcmp("-a",argv[1]) == 0)
     10         printf("功能a\n");
     11         if(strcmp("-b",argv[1]) == 0)
     12         printf("功能b\n");
     13         if(strcmp("-c",argv[1]) == 0)
     14         printf("功能c\n");
     15         if(strcmp("-ab",argv[1]) == 0)
     16         printf("功能ab\n");
     17         if(strcmp("-ac",argv[1]) == 0)
     18         printf("功能ac\n");
     19         if(strcmp("-bc",argv[1]) == 0)
     20         printf("功能bc\n");
     21         if(strcmp("-abc",argv[1]) == 0)
     22         printf("功能abc\n");
     23         return 0;
     24 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    运行:
    在这里插入图片描述

    五、代码获取环境变量

    上面的getenv就是一种代码获取环境变量的方法。

    1. main函数的第三个参数char* env[]

    文件test3.c

      1 #include<stdio.h>
      2 int main(int argc, char* argv[], char* env[])
      3 {
      4         int i = 0;
      5         for(;env[i]; ++i)
      6         {
      7                 printf("env[%d] : %s\n", i, env[i]);
      8         }
      9         return 0;
     10 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    2. 通过第三方变量environ获取

    文件test3.c

      1 #include<stdio.h>
      2 int main(int argc, char* argv[], char* env[])
      3 {
      4         extern char** environ;
      5         int i = 0;
      6         for(;environ[i]; ++i)
      7         {
      8                 printf("env[%d] : %s\n", i, environ[i]);
      9         }
     10         return 0;
     11 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    六、环境变量的组织方式

    每个进程运行的时候都会有一张环境变量表,它本质是一个字符指针数组,每个指针指向一个以'\0'为结尾的字符串。
    在这里插入图片描述


    总结

    以上就是今天要讲的内容,本文介绍了环境变量的相关概念。本文作者目前也是正在学习Linux相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
    最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

  • 相关阅读:
    [附源码]计算机毕业设计springboot教育企业网站
    网站有反爬机制就爬不了数据?那是你不会【反】反爬
    739. 每日温度【单调栈】
    【Verilog】画出下列wave信号波形图
    瑞吉外卖 —— 4、菜品分类管理
    重温javascript --(三)对象
    笔试题:金额拆分
    【LeetCode】297.二叉树的序列化与反序列化
    【Python脚本进阶】2.4、conficker蠕虫(上):Metasploit攻击Windows SMB服务
    Html5中的input标签之多少
  • 原文地址:https://blog.csdn.net/xjjxjy_2021/article/details/130875975