【Linux进程】环境变量和命令行参数 {常见的环境变量:PATH,HOME;在代码中获取环境变量,环境变量的组织方式;环境变量具有全局属性;命令行参数}

环境变量

【Linux进程】环境变量和命令行参数 {常见的环境变量:PATH,HOME;在代码中获取环境变量,环境变量的组织方式;环境变量具有全局属性;命令行参数}_第1张图片

一、基本概念

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数

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

    举几个栗子:

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

    2. 系统命令其实也是一个个程序。但在命令行上输入某些系统命令时(如cd, pwd, cp等),我们从不在命令前加其所在路径但系统却可以找到并执行他。这是由于PATH环境变量记录了命令的搜索路径。


二、常见的环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录
  • SHELL : 当前Shell,它的值通常是/bin/bash。

查看环境变量方法

  1. echo $NAME:显示某个环境变量的值
  2. env:显示所有的环境变量

2.1 PATH

为什么有些系统指令可以直接执行,不需要带路径;而我们编写的程序需要带路径才能执行?

这是由于PATH环境变量记录了命令的搜索路径。所有的系统命令都可以在PATH环境变量所记录的路径下找到。

想不带路径直接执行自己编写的程序?

  1. 将我们编写的可执行程序的所在路径加入环境变量PATH当中

  2. export 命令用于导出环境变量,并使其对所有程序可见

    export PATH=$PATH:file_path //追加
    export PATH=file_path //覆写
    
  3. 此时就可以直接通过可执行文件名运行程序了,不需要再加路径。

请注意:此更改仅对当前会话有效。如果你想要永久生效,应将该目录添加到你的shell配置文件中(例如,对于Bash来说是 ~/.bashrc)。


2.2 HOME

用于指定用户的主工作目录

不同登录用户的HOME环境变量不同

【Linux进程】环境变量和命令行参数 {常见的环境变量:PATH,HOME;在代码中获取环境变量,环境变量的组织方式;环境变量具有全局属性;命令行参数}_第2张图片

cd ~命令可以直接切换到家目录,就是因为HOME环境变量记录了家目录的路径。


三、在代码中获取环境变量

3.1 环境变量的组织方式

C/C++的main函数共有三个参数:int main(int argc, char *argv[], char *env[]);

  1. argc:命令行参数的个数,默认为1。
  2. argv:命令行参数表,默认保存./program
  3. env:环境变量表

每个进程都会收到一张环境变量表,环境变量表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境变量字符串。
环境变量表以NULL结尾

【Linux进程】环境变量和命令行参数 {常见的环境变量:PATH,HOME;在代码中获取环境变量,环境变量的组织方式;环境变量具有全局属性;命令行参数}_第3张图片

提示:bash也是一个进程,他也会收到环境变量表。在执行基本指令时不需要带路径是因为bash获取到了环境变量PATH。


3.2 获取环境变量的三种方法

方法一:通过main函数的第三个参数获取环境变量表

#include 
int main(int argc, char *argv[], char *env[])
{
	int i = 0;
	while(env[i] != NULL){
		printf("%s\n", env[i]);
        ++i;
	}
	return 0;
}

方法二:通过全局变量environ获取环境变量表

#include 
#include 
int main(int argc, char *argv[])
{
	int i = 0;
	while(environ[i] != NULL){
		printf("%s\n", environ[i]);
        ++i;
	}
	return 0;
}

注意:environ定义在头文件中,是一个char** 类型,和env的类型和用法完全相同。

方法三:通过系统调用getenv获取指定的环境变量

#include 
#include 
int main(int argc, char *argv[])
{
	printf("%s/n", getenv("PATH"));
	return 0;
}

注意:getenv函数的声明包含在头文件


四、环境变量具有全局属性

我们知道了每个进程都会收到一张环境表,那么环境表是从哪来的呢?答案是,从其父进程继承来的。

环境变量具有全局属性,可以被子进程继承下去。

测试代码:

#include 
#include 
int main()
{
	char * env = getenv("MYENV");
	if(env){
		printf("MYENV: %s\n", env);
	}
    else{
        printf("variable do not exist!\n");
    }
	return 0;
}

直接运行,发现该环境变量根本不存在:

在这里插入图片描述

我们首先要导出环境变量 export MYENV="hello world"
再次运行程序,发现进程获取到该环境变量了:
【Linux进程】环境变量和命令行参数 {常见的环境变量:PATH,HOME;在代码中获取环境变量,环境变量的组织方式;环境变量具有全局属性;命令行参数}_第4张图片

bash是所有在命令行上启动的进程的父进程,通过上面的测试就说明环境变量是可以被子进程继承下去的!

注意:

  • export的作用是将局部变量导出为环境变量,使其可以被当前shell进程的子进程继承,并在整个环境中可见和使用。如果不使用export命令,设置的变量是局部变量不是环境变量只在当前shell进程中有效,不会被子进程继承。
  • 以上的操作均只在本次登录有效,重新登录后所有的自定义变量都会被清除。若想长期有效需修改对应的配置文件,shell进程在被创建时会从文件中载入环境变量,并供所有的子进程继承。

五、命令行参数

5.1 什么是命令行参数?

命令行参数是在执行命令时,通过命令行传递给程序的额外信息。它们是一些字符串值,用于向程序提供输入、配置选项或操作参数等。

在命令行中,通常以空格分隔的形式提供命令和参数。命令行参数可以分为两类:

  1. 位置参数(Positional Arguments):位置参数是按照它们在命令行中出现的顺序传递给程序的参数。程序可以根据位置来解析和使用这些参数。例如,program arg1 arg2中的arg1arg2就是位置参数。如指令mv dir1 dir2, cp dir1 dir2等等。

  2. 选项参数(Option Arguments):选项参数是以某种特定的格式传递给程序的参数,通常以短横线(-)或双短横线(–)开头。选项参数用于配置程序的行为或提供特定的操作。例如,program -f filename中的-f就是一个选项参数,用于指定要操作的文件名。如指令ls -a -l, rm -r -f等等

命令行参数可以帮助程序根据不同的需求进行不同的操作或配置。在C语言中,可以通过main函数的参数argv来获取命令行参数表,并在程序中进行处理和使用命令行参数。

每个进程都会收到一张命令行参数表,命令行参数表是一个字符指针数组,每个指针指向一个以’\0’结尾的命令行参数字符串。
命令行参数表同样以NULL结尾


5.2 如何使用命令行参数?

C/C++的main函数共有三个参数:int main(int argc, char *argv[], char *env[]);

  1. argc:命令行参数的个数,默认为1。
  2. argv:命令行参数表,默认保存./program
  3. env:环境变量表

一个接收命令行选项参数的简单程序:

int main(int argc, char** argv){      
  if(argc == 1)    
  {    
    cout << "Run without option!" << endl;                                                                                       
    return 0;    
  }    
    
  //程序中内置的选项    
  vector<string> options;    
  options.push_back("-a");    
  options.push_back("-b");    
  options.push_back("-c");    
  options.push_back("-d");    
    
  //匹配查找输入的选项    
  for(int i = 1; i<argc; ++i){    
    auto ret = find(options.begin(), options.end(), argv[i]);    
    if(ret != options.end())    
    {    
      cout << "option: " << argv[i] << endl;                                                                                     
    }    
    else{    
      cout << "option " << argv[i] << " is not available!" << endl;     
      break;    
    }    
  }
  return 0;
}

运行结果:

【Linux进程】环境变量和命令行参数 {常见的环境变量:PATH,HOME;在代码中获取环境变量,环境变量的组织方式;环境变量具有全局属性;命令行参数}_第5张图片


5.2 命令行参数是从哪里来的?

  • 当我们在Shell中输入一个命令并按下回车键时,Shell会解析这个命令,并将命令及其参数传递给相应的程序。Shell进程会将命令行参数作为程序的输入之一,并将其传递给新创建的子进程。
  • 事实上,虽然Shell进程是最常见的传递命令行参数的进程,但其他进程也可以通过适当的机制来传递命令行参数给它们创建的子进程。
  • 总之一句话,命令行参数由父进程传递给子进程

六、相关命令总结

  1. echo $NAME:显示指定名称的shell变量和环境变量的值。如果该变量没有被定义,则不会显示任何内容。

  2. env:显示所有的环境变量和其值。

  3. export:将shell变量导出为环境变量。该命令将指定的shell变量添加到环境变量表中,使其在当前shell会话中可用,并在子进程中也可用。

  4. set:显示本地定义的shell变量和环境变量的值。该命令会显示所有的本地定义的shell变量和环境变量,包括当前shell会话中定义的变量和从父进程继承的变量。

  5. unset:删除指定名称的shell变量和环境变量。该命令会删除指定的shell变量或环境变量,使其在当前shell会话中不再可用。如果该变量是一个环境变量,则该命令只会在当前shell会话中删除该变量,而不会影响其他进程。

你可能感兴趣的:(Linux,linux,服务器,环境变量,shell,命令行参数)