【Linux】下令行参数与环境变量

打印 上一主题 下一主题

主题 837|帖子 837|积分 2511



  
一、下令行参数

1.1 下令行参数是什么?

在我们学习C语言的时间,没怎么使用过main函数的参数,实际上main函数是可以有参数的。int main(int argc, char *argv[]),其中main函数中的两个参数就叫做下令行参数。
这两个参数具体有什么作用呢?接下来使用代码进行解答。
  1. #include<stdio.h>                                                                                                                           
  2.    
  3. int main(int argc , char* argv[])   
  4. {   
  5.     int i = 0;   
  6.    
  7.     for(; i < argc ; i++)   
  8.     {   
  9.         printf("%d %s\n",i,argv[i]);   
  10.     }   
  11.    
  12.     return 0;   
  13. }   
复制代码

当使用下令行启动步伐,上图便是运行步伐后的效果,细心一点可以发现,将下令行上的指令看成一个长字符串,以空格为分隔符,将长字符串分为几个短字符串,参数argc就是短字符串的个数,参数argv是指针数组,用来存放分割后短字符串的地点。
在下令行上输入的指令,会被Shell或OS(操纵系统)自动处置处罚为短字符串,将短字符串的个数传给argc,并生成数组用来存放短字符串的地点,再将数组传给argv。


1.2 设计下令行参数的意义

下令行参数可以使同一个步伐,通过不同的选项,实现不同的功能。
下令行参数,可以支持各种指令级别的下令行选项的设置,在以前学到的指令中,给指令带上不同的选项,就可以实现不同的功能,就是这个原理。

下面我将编写一个下令行级别的盘算器代码为各人演示下令行参数应该怎样使用。
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. int main(int argc , char* argv[])
  5. {
  6.     // 这里argc必须等于4,指令需要能够拆分为四个短字符串
  7.     // 第一个字符串为程序名
  8.     // 第二个字符串为需要进行何种操作
  9.     // 第三、四个字符串为操作数
  10.    
  11.     if(argc != 4)
  12.     {
  13.         // 当字符串的个数不为4时,则说明输入错误,输出操作说明
  14.         printf("Usage:%s op[add|sub|mul|div] d1 d2\n",argv[0]);
  15.         // argc 必定大于0,启动程序需要输入程序名
  16.         return 1;
  17.     }
  18.    
  19.     // 将操作数从字符串转化为整形
  20.     int d1 = atoi(argv[2]);
  21.     int d2 = atoi(argv[3]);   
  22.    
  23.     if(strcmp(argv[1],"-add") == 0)                                                           
  24.     {                                                                                         
  25.         // add , 将两个操作数相加                                                            
  26.         printf("%d + %d = %d\n" , d1 , d2 , d1 + d2);                                         
  27.     }                                                                                         
  28.     else if(strcmp(argv[1],"-sub") == 0)                                                      
  29.     {                                                                                         
  30.         // sub , 将两个操作数相减                                                            
  31.         printf("%d - %d = %d\n" , d1 , d2 , d1 - d2);                                         
  32.     }                                                                                         
  33.     else if(strcmp(argv[1],"-mul") == 0)                                                      
  34.     {                                                                                         
  35.         // mul , 将两个操作数相乘                                                            
  36.         printf("%d * %d = %d\n" , d1 , d2 , d1 * d2);      
  37.     }      
  38.     else if(strcmp(argv[1],"-div") == 0)      
  39.     {      
  40.         // 当被除数为0时,操作错误      
  41.         if(d2 == 0)      
  42.             printf("%d / %d = error , div zero\n", d1 ,d2);      
  43.         // div , 将两个操作数相除      
  44.         else      
  45.             printf("%d / %d = %d\n" , d1 , d2 ,d1 / d2);                                                                                    
  46.     }
  47.     else
  48.     {
  49.         // 当操作选项不为上述四个操作时,则说明输入错误,输出操作说明
  50.         printf("Use error , you should use right command line\nUsage:%s op[add|sub|mul|div] d1 d2\n",argv[0]);
  51.     }
  52.     return 0;
  53. }
复制代码


二、环境变量

2.1 环境变量的根本概念



  • 环境变量一般是指在操纵系统中用来指定操纵系统运行环境的一些参数
  • 如:我们在编写C/C++代码的时间,在链接的时间,从来不知道我们的所链接的动态静态库在哪里,但是照旧可以链接乐成,生成可实行步伐,缘故原由就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,另有在系统当中通常具有全局特性
  • 在下令行中输入echo $环境变量 下令可以检察当前环境变量的内容,这里环境变量前必须加上 $ ,否则环境变量会被当成字符串输出。

2.2 常见环境变量

2.2.1 PATH

之前文章提到过,要实行一个下令就必须找到对应的可实行步伐,当我们平常要运行我们本身编写的步伐时,都需要带上./来代表该步伐的路径,没有./则找不到该步伐导致无法运行,但是当我们使用指令(本质上也是步伐)的时间发现并不需要./来找到它的路径,例如ls、pwd、which等下令,它们可以使用路径来运行指令,也可以直接使用指令的名字来运行指令,导致指令不需要路径就可以运行的缘故原由就是PATH。

我们可以使用echo $PATH来检察环境变量PATH中的内容,这里必须加上 $ ,否则PATH会被当成字符串输出。
检察PATH中的内容发现它的内容是一个字符串,以 : 为分隔符,可以看出这个字符串是由很多路径组成的。当用户在下令行中输入一个指令或步伐名时,系统会在PATH环境变量所指定的目次中搜索该指令或步伐的可实行文件。假如找到了,系统就会实行它;假如没有找到,就会报错。


2.2.1.1 通过下令行配置PATH


  • 向PATH中添加路径,可以使用PATH = PATH:/需要添加的路径,即可向PATH中添加路径

  • 将PATH中的部分路径删除,可以使用PATH=/所需要的路径

    当我们将PATH中所有的路径全部删除,会发现系统中的大部分指令无法正常的使用,但是当我们重新登录操纵系统后,就可以发现指令可以正常使用了。

    这是因为操纵系统中有很多配置文件,有一类配置文件在下令行启动的时间会被读取,将预设的环境变量和对应的内容导入进操纵系统。我们这里修改的环境变量只限于本次登录,重新登录后,环境变量会被重新加载。

2.2.1.2 使本身的步伐像系统中指令一样运行


  • 将本身编写的步伐的路径添加的PATH中,可以使用PATH = PATH:/本身步伐所在的路径

  • 将本身编写的步伐拷贝到PATH中的任意一个路径中,本质上就是步伐安装


2.2.2 HOME

环境变量HOME指定了当前用户的家目次,这个路径通常看起来像是/home/用户名(对于root用户则是/root)。
当我们登录账号时,会发现普通账号与root账号的家目次是不相同的,是因为操纵系统中有一个环境变量在我们登录时就存在了,当我们登录账号时,它会对用户进行辨认,然后对不同的用户设置它不同的环境变量HOME。

我们经常使用 cd ~ 用来使用户快速回抵家目次,本质上就是波浪线 ~ 是对HOME环境变量值的快捷方式,表示当前用户的加目次。

2.2.3 PWD

环境变量PWD用于存储用户当前所在的目次(工作目次)的完备路径。
我们使用的指令pwd就是从环境变量PWD中读取,得到用户当前所在的工作目次。


2.3 检察操纵系统中所有的环境变量(env)

在Linux系统中,env下令是一个非常重要的工具,用于显示或设置环境变量。当在下令行中直接输入env下令并按下回车键时,系统会列出当前设置的所有环境变量以及它们的值。


2.4 怎样在进程中获取环境变量

2.4.1 getenv函数

在Linux中,getenv函数是一个尺度C库函数,可以用于获取环境变量中的内容。char *getenv(const char *name);


  • name:指向以NULL结尾的字符串的指针,该字符串为要查询的环境变量的名称。

  1. #include<stdio.h>   
  2. #include<stdlib.h>   
  3.    
  4. int main()   
  5. {   
  6.     printf("PATH:%s\n",getenv("PATH"));   
  7.     printf("HOME:%s\n",getenv("HOME"));                                                                                                     
  8.    
  9.     return 0;   
  10. }   
复制代码


2.4.2 下令行的第三个参数(char* env[])

在上面下令行参数中,我们讲到了main函数可以不带参数,可以带两个参数,实际上main函数还可以带第三个参数char* env[],这第三个参数是指向环境变量字符串的指针数组,在操纵系统启动的时间会一张是环境变量表,这张表中存放的就是环境变量字符串的地点。

Shell在启动我们步伐的时间,可以选择给我们的进程(main)提供两个表,一个是下令行参数表,一个是环境变量表。
  1. #include<stdio.h>   
  2. #include<sys/types.h>   
  3. #include<unistd.h>   
  4.    
  5. int main(int argc,char* argv[],char* env[])   
  6. {   
  7.     int i = 0;   
  8.    
  9.     for(; env[i] ; i++)   
  10.     {   
  11.         printf("my pid: %d , env[%d]: %s\n",getpid(),i,env[i]);                                                                           
  12.     }                                 
  13.                                       
  14.     return 0;   
  15. }   
复制代码
当我们运行上面的步伐时,可以发现步伐打印出的环境变量与在下令行中使用env指令打印出的环境变量根本上完全一致。


2.4.3 全局变量environ(C语言/C++)

在Linux中,假如你在C语言步伐中想要检察环境变量,你可以通过访问全局变量environ来实现。environ是一个指向以NULL结尾的字符指针数组的指针,每个指针都指向一个以NULL结尾的字符串。各人也可以明白为全局变量environ就是指向env表的指针。
  1. #include<stdio.h>      
  2. #include<sys/types.h>      
  3. #include<unistd.h>      
  4.       
  5. int main()      
  6. {      
  7.     extern char** environ;      
  8.     int i = 0;      
  9.       
  10.     for(; environ[i] ; i++)      
  11.     {      
  12.         printf("my pid: %d , environ[%d]: %s\n",getpid(),i,environ[i]);                                                                     
  13.     }                                                                                                   
  14.                                                                                                       
  15.     return 0;                                                                                          
  16. }
复制代码


2.5 进程怎样获取环境变量

之前的文章中讲到过,在下令行上启动的进程都是Shell/bash的子进程,子进程的下令行参数和环境变量都是父进程传给子进程的。
在解说PATH的时间提到过,当我们修改PATH再重新登录Shell后,PATH会被重新生成,这是因为我们修改的是bash进程内的环境变量,每次重新登录,操纵系统都会给我们重新生成bash解释器并且新的bash解释器会自动从脚本配置文件读取形本钱身的环境变量信息表,环境变量信息是以脚本配置文件形式存在的,bash进程的环境变量就是从脚本配置文件中获取的。
2.5.1 .bash_profile文件

位置:位于用户的家目次下,路径通常为/home/用户名/.bash_profile,当我们在家目次下输入下令ls -al 会发现一个隐藏文件.bash_profile。
作用:在用户登录的过程中,系统会首先检查是否存在.bash_profile文件,假如存在,则会实行其中的下令,它主要用于设置用户级别的环境变量和实行用户特定的初始化脚本。

2.5.2 .bashrc文件

位置:同样位于用户的家目次下,路径为/home/用户名/.bashrc。当我们在家目次下输入下令ls -al 会发现一个隐藏文件.bashrc。
作用:该文件是bash/Shell的启动脚本,用于配置用户的交互式Shell环境。每次启动一个新的bash/Shell时,.bashrc文件都会被实行,通常在.bash_profile文件中通过一行代码来加载.bashrc,以确保登录Shell也能加载.bashrc中的配置。

2.5.3 /etc/bashrc文件

位置:位于系统的/etc目次下,另有一个文件/etc/bashrc。
作用:该文件为系统中所有运行bash/Shell的用户提供全局的bash配置。通常在.bashrc文件中通过一行代码来加载/etc/bashrc,当bash/Shell被打开时,该文件会被读取并实行,它通常包罗一些对所有效户都适用的配置信息,如环境变量设置、别名界说等。


2.6 怎样向进程中设置环境变量

在Shell/bash中不仅仅有系统的环境变量,还可以本身添加环境变量,下面为各人先容两种添加环境变量的方法。
2.6.1 在下令行中设置环境变量

我们可以在下令行中设置变量,如下图,我添加了一个变量MYENV_1,并且这个变量可以通过echo指令显示变量的内容,但是当使用env指令并通过管道筛选出MYENV_1变量却显示不出来变量的内容,显然是因为这个变量没有被添加到环境变量中,其实这种变量我们称之为本地变量,本地变量与环境变量的区别在背面讲到,想要将本地变量添加到环境变量,使用export 本地变量名即可。


除了先将变量界说出来再使用export添加到环境变量,还可以在界说变量的同时将变量export添加到环境变量中,例如:export MYENV_2=1314。

要留意的是以export指令添加环境变量只在本次登录有效,当重新登录Shell/bash时,我们添加的环境变量就不会存在,因为我们添加的环境变量实际上是添加到Shell/bash进程中的,也就是内存中,重新登录后也就不会存在我们添加的环境变量。
当我们使用下令行启动进程,用来输出该进程的环境变量,发现我们添加的环境变量在该进程(Shell/bash的子进程)也存在,也能证实子进程的下令行参数和环境变量都是父进程传给子进程的。


2.6.2 修改系统中的配置文件

想要每次启动Shell/bash时,本身设置的环境变量都存在,可以通过修改 ~/.bashrc 、~/.bash_profile等文件来永久设置环境变量
我们在下令行中怎样添加环境变量的,就在配置文件中怎么写。



2.7 本地变量 vs 环境变量

2.7.1 本地变量

本地变量是在Shell脚本或下令行界面中界说的变量,本地变量只在bash内部有效,无法被子进程获取
2.7.2 环境变量

环境变量是对于运行在当前用户环境中的所有进程都可见的变量。它们通常由操纵系统或Shell在启动时设置,但也可以由用户或步伐在运行时设置。
2.7.2.1 环境变量通常是具有全局属性的

环境变量通常具有全局属性,这意味着它们一旦被设置并导出到环境中,就会对当前Shell/bash进程及其启动的任何子进程可见。
当我们运行下面这个步伐的时间,可以发现子进程的子进程也可以获取到环境变量,也可以证实环境变量通常具有全局属性的。
  1. #include<stdio.h>                                                                                                                           
  2. #include<sys/types.h>   
  3. #include<unistd.h>   
  4. #include<stdlib.h>   
  5.    
  6. int main()   
  7. {   
  8.     int id = fork();   
  9.    
  10.     if(id == 0)   
  11.     {   
  12.         extern char** environ;   
  13.         int i = 0;   
  14.         
  15.         for(; environ[i] ; i++)   
  16.         {   
  17.             printf("my pid: %d , environ[%d]: %s\n",getpid(),i,environ[i]);   
  18.         }                                                                     
  19.     }                                                  
  20.          
  21.     return 0;      
  22. }  
复制代码


2.8 下令常见分类

不知道各人在上面部分有没有留意到一个小细节,就是当把环境变量置为空时,大部分都无法运行,但是照旧有小部分下令可以运行,因为下令被分为了两种,常见下令与内建下令。

2.8.1 常见下令

常见下令是Linux系统中的实用步伐部分,它们通常位于/usr/local/bin、/usr/bin、/usr/local/sbin或/usr/sbin等目次下。这些下令由独立的步伐实现,当这些下令运行在下令行上启动时,Shell/bash会创造一个子进程来运行这个下令,当我们将环境变量PATH置为空以后,那么常见下令就不能够通过下令名直接启动进程。
例如:


  • ls:列出目次内容。
  • cp:复制文件或目次。
  • mv:移动或重命名文件。
  • rm:删除文件或目次。
  • ps:显示当前运行的进程。
  • grep:在文件中搜索指定文本。
  • tar:用于压缩息争压文件和目次。

2.8.2 内建下令

内建下令是Shell/bash进程的一部分,它们由Shell/bash进程辨认并在Shell/bash进程内部完成运行。与常见下令不同,实行内建下令时不需要创建新的子进程,因此它们的实行速度通常更快。
例如:


  • cd:切换工作目次。
  • pwd:显示当前工作目次的路径。
  • echo:输出字符串或变量值。
  • read:从尺度输入读取数据。
  • set:设置或显示Shell环境变量与本地变量。
  • unset:删除Shell环境变量与本地变量。

2.9 和环境变量相关的下令


  • echo: 显示某个本地变量与环境变量值

  • env: 显示所有环境变量
  • export: 设置一个新的环境变量

  • unset: 打扫本地变量和环境变量

  • set: 显示本地界说的shell变量(本地变量)和环境变量


结尾

假如有什么建议和疑问,或是有什么错误,各人可以在批评区中提出。
盼望各人以后也能和我一起进步!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表