Linux系统编程:详解环境变量

目录

一. 环境变量的基本概念

1.1 什么是环境变量

1.2 环境变量的功能测试

二. 与环境变量相关的操作 

三. 环境变量的组织方式

四. 通过代码获取环境变量的值

五. 总结


一. 环境变量的基本概念

1.1 什么是环境变量

环境变量是用于指定操作系统相关参数的、全局的变量。通过env指令,可以查看系统中全部的环境变量。

下面是几个常见的环境变量:

  • PATH:指令的搜索路径
  • HOME:特定用户的家目录,即:用户登录时默认所在的路径。
  • SHELL:当前的shell外壳,一般为/bin/bash

查看环境变量值的方法:echo $环境变量名

环境变量有如下几点特性:

  • 某个进程环境变量是从它的父进程中继承下来的。
  • 默认所有的环境变量都会被子进程继承。
  • 环境变量具有全局属性。

1.2 环境变量的功能测试

  • 测试PATH

PATH表示指令的默认搜索路径,我们首先通过echo $PATH,获取当前的PATH值,如图1.1所示,我们看到所有的路径被:分割,OS会依次从PATH的路径中搜索用户输入的指令,直到找到指令为止,如果到了最后一个路径还没有找到,那么OS就认为指令不存在,无法执行。

图1.1 环境变量PATH的值

我们创建编译下面的代码,生成可执行程序mytest.exe,分别在命令行中输入./mytest.exe和mytest.exe,前者成功运行,后者运行失败,详见图1.2。这是因为mytest.exe并不是一条指令,mytest.exe文件所在的路径不包含在PATH值内。

结论:Linux系统内置的指令不需要路径,输入指令名称就可以运行。用户自主编译生成的可执行程序,需要加上路径./XXX才可以运行。

Linux系统编程:详解环境变量_第1张图片 图1.2 加路径和直接输入可执行程序名称时的运行结果

接下来,通过指令 export PATH=$PATH:(pwd)  修改修改环境变量PATH的值,然后再次在命令行中直接输入mytest.exe,可见这次程序运行成功了(详见图1.3)!此时通过echo $PATH查看PATH的值,可见当前路径被加入到了PATH中,因此直接输入mytest.exe可以成功运行程序。

Linux系统编程:详解环境变量_第2张图片 图1.3 改变环境变量PATH的值
  • 测试HOME 

在两个终端下,分别使用普通用户zhangHHH和root用户登录,分别使用echo $HOME指令在不同用户登录的情况下查看环境变量HOME的值,可以看到HOME就是用户的家目录。

Linux系统编程:详解环境变量_第3张图片 图1.4 在普通用户和root用户下测试HOME的值

二. 与环境变量相关的操作 

  • echo $ -- 获取环境变量值 

语法:echo $val_name,可以输出环境变量的值。这里的$不能省略,如果省略,那么输出的就是环境变量本身了,如echo PATH输出PATH。

  • export -- 定义环境变量 

语法:export 环境变量名称=值,如:export VAL=1234,就定义了一个名称为Val,值为1234的环境变量,这个变量具有全局属性。 

  • env -- 获取系统中的所有环境变量

如果我们通过export设定了环境变量,那么使用env同样能够查到。

  • unset -- 清除环境变量

语法:unset [环境变量名称]

图2.1 环境变量相关操作
  • putenv -- 在程序中导入环境变量 

语法:putenv("[valName]=VAL") 

putenv是C语言提供的函数,被包含在头文件

如:putenv("MYVAL=1234"),就导入了名为MYVAL,值为1234的环境变量。导入父进程环境变量的子进程,也会接收到这个环境变量。

三. 环境变量的组织方式

一个main函数,最多可以有三个形参。即:main(int argc, char* argv[], char* env[]),其中argc为运行可执行程序时命令行参数的个数,argv为指向命令行参数列表的指针数组,env为指向环境变量列表的指针数组。

env指向一个存有若干char*类型变量的指针数组,数组以NULL结尾,数组中的每个数据指向一个环境变量的值,见图3.1。argv的组织方式与env基本完全相同,只不过不会以NULL结尾,但会有argc来获取记录选项的个数。

Linux系统编程:详解环境变量_第4张图片 图3.1 环境变量的组织

四. 通过代码获取环境变量的值

  • 方法1:通过main函数的第三个参数获取

main(int argc, char* argv[], char* env[]))函数的第三个参数为指向环境变量列表的指针数组,通过evn[i],可以依次获取每个环境变量。代码4.1通过for循环,以env[i] != NULL为循环条件,依次打印每个环境变量的值。程序运行结果见图4.1。

代码4.1:通过main函数第三个参数获取环境变量

#include    
      
main(int argc, char* argv[], char* env[])    
{    
    for(int i = 0; env[i]; ++i)    
    {    
        printf("env[%d] = %s\n", i, env[i]);                                                                                       
    }   
 
    return 0;    
}   
Linux系统编程:详解环境变量_第5张图片 图4.1 通过代码4.1的运行结果
  •  方法2:通过第三方变量char **environ获取

变量char **environ被包含在头文件中,在使用时,需要显示的包含头文件或者在程序中声明外部变量extern char **environ。代码4.2展示了environ的用法。

代码4.2:通过第三方变量environ获取环境变量  

#include    
#include    
    
int main()                                                                                                                           
{                                                         
    for(int i = 0; environ[i]; ++i)                       
    {                                                     
        printf("environ[%d] = %s\n", i, environ[i]);      
    }                                                     
    return 0;                                             
} 
  • 方法三:通过函数getenv获取

语法:char* env_name = getenv("环境变量名称")

如果企图获取不存在的环境变量,那么程序会在运行期间报错Segmentation fault。

代码4.3:通过getenv函数获取环境变量值

#include    
int main()                                                                                                                           
{             
    char* path = getenv("PATH");    
    char* home = getenv("HOME");    
    printf("PATH:%s\n", path);      
    printf("home:%s\n", home);    
    return 0;                     
} 
图4.2 代码4.3的运行结果

补充知识:

我们可以直接在命令行中使用  val_name=val 类似的指令来定义局部变量的值,但是,这并不属于全局变量,如果我们企图使用getenv获取它们的值,会在运行期间报错Segmentation fault。

这里由于提到了main函数的三个参数,因此也顺便对int argc和char* argv[]进行解读。argv表示可执行程序运行时命令行参数的个数,如果仅输入./XXX运行,那么命令行参数的个数就为1。

命令行参数的主要功能是让同一个函数,根据输入的选项,执行不同的代码。如代码4.4所示,我们要求至少有两个命令行参数,如果只输入一个(argc < 2),那么程序报错退出,如果输入选项-a,那么就执行function1,如果输入选择-b,那么就执行function2。

结论:选项 + 命令行参数可以实现同一份代码执行不同工作。

代码4.4:通过命令行参数让同一份代码执行不同工作

  #include    
  #include    
      
  int main(int argc, char *argv[], char *env[])    
  {    
      //至少有两个命令行参数(一个选项)    
      if(argc < 2)    
      {    
          std::cout << "至少两个命令行参数" << std::endl;    
      }    
      
      if(strcmp(argv[1], "-a") == 0)    
      {    
          std::cout << "function1" << std::endl;    
      }    
      else if(strcmp(argv[1], "-b") == 0)                                                                                                                                                                                                                                     
      {    
          std::cout << "function2" << std::endl;    
      }    
      
      return 0;    
  }  
Linux系统编程:详解环境变量_第6张图片 图4.3 代码4.4的运行结果

五. 总结

  • 环境变量是用于定义操作系统相关参数的全局变量,主要有PATH、HOME、SHELL等,每个进程的环境变量从它的父进程中继承。
  • 通过echo $、export、unset、env等指令,可以实现对环境变量的增删查改。
  • 环境变量是通过指针数组来组织的,char* env[]可作为main函数的第三个参数。
  • 有三种方法可以实现在代码中获取环境变量的值:通过main函数的第三个参数char* env[]、通过第三方变量extern char **environ、通过getenv函数。
  • main函数的第一个参数argc表示命令行参数的个数,第二个参数为指向命令行参数存储地址的指针数组,通过 命令行参数+选项 的组合使用,可让一份代码根据用户需要实现不同的功能。

你可能感兴趣的:(Linux系统和网络,linux,运维,服务器)