Ⅰ、什么是环境变量?
在操作系统书上的定义是;指在操作系统中用来指定操作系统运行环境的一些参数。比如我们想在Linux上执行我们自己写的可执行程序要指明路径如果不指明路径会 “command not found
”,那我们知道命令都是一个个的可执行文件为什么命令不用在前面加路径呢?这就是因为有环境变量的存在,换一句话来说更形象的描述环境变量就是:环境变量就是一些特殊的全局变量来记录操作系统的一些参数。可能你不太理解这句话看完这篇博客我相信你会明白。
Ⅱ、命令行参数
我们先从命令行参数引入,我们想一想操作系统是怎么知道我们要执行的命令的?我们写的main函数有没有参数?可能我们之前看过main函数写参数的代码,下面我们来看下面这段代码思考这两个问题。
#include<stdio.h>
2 int main(int argc , char* argv[])
3 {
4 for(int i=0;i < argc; i++)
5 {
6 printf("argv[%d]:%s\n", i , argv[i]);
7 }
8 return 0;
9 }
可能看上去不知道这段代码是干什么的,先来解释argc和argv是什么东西?
argv:是一个指针数组的数组名,这个数组里面存的就是命令行参数的字符串,比如我们输入“ls -a”那么argv就会以空格为分割存“ls”和“-a”这两部分。那么argv这个数组是谁在维护的呢?答案是bash,bash会在进程中维护这个表。
argc:说完argv以后argc就很好了解了,argc的类型是int他就是记录argv这个指针数组记录的指针的个数。
看到这个结果我们回答上面的那两个问题:
一、通过argv这个指针数组我们就可以区分不同的命令和不同的命令和选项的搭配。
二、main函数是有参数的。
Ⅲ、初识环境变量的作用
下面我们来逐步解释我们在第一部分的问题(为什么命令不用在前面加路径呢?)下面我们看一个现象:
显然我们是不能不加路径去执行我们的可执行文件,因为不带路径操作系统找不到那个可执行文件在哪。
我们可以用file命令查ls命令我们可以看见他是一个可执行文件。那么按道理来说的话我们应该输入usr/bin/ls才可以执行。那为什么不需要呢?这时因为有 PATH 这个环境变量的存在。那PATH是什么东西?我们先来解决如何不加路径可以执行我们的代码再来说明这个环境变量。
我们看一下这两句指令,第一个sudo执行把我们的test.exe可执行文件移到/usr/bin这个目录下,第二个指令是确定/usr/bin里已经有了我们的可执行文件,下面我们来看一个现象。
我们发现我们可以不加路径去执行我们自己的可执行文件和系统里那些命令达到了一样的效果。
我们可以得出一个结论:并不是ls在执行的时候不加路径是bash才执行的时候自己加上去了。下面我们引出bash在指令前加的东西PATH。
下面我们在这里先插入另外一个问题:指令是如何执行的?
Ⅳ、bash执行指令
我们在上面说到bash会在进程中维护一个命令参数表,其实bash还会维护一个环境变量表。
那么我们就有一个问题了,环境变量表是从哪来的?
环境变量表最开始是从系统的配置文件(bashrc和bash_profile)中,这两个文件在用户的家目录下。在Centos中这两个文件叫bashrc和bash_profile,在Ubuntu中是bashrc和profile。
当用户登录的时候系统会先创建bash进程,bash会从这两个文件中读取并创建一个环境变量表(一个指针数组)。输入命令以后bash先在命令参数表中读取命令再在环境变量表中查找对应的环境变量,找到对应的命令执行。
Ⅴ、常见的环境变量
一、PATH
PATH:指定命令的搜索路径
1、如何查PAHY?
$PATH(环境变量名)
2、如何改PATH?
PATH=新的路径
我们可以看见PATH内容已经变成了我们可执行文件的路径,这种改变是内存级的退出登录重新进入bash就会重新从配置文件中重新读取。
PATH=$(PATH):新的路径
这种不会覆盖原本的内容而是在后面添加,这种也是内存级的重新进入也是会消失的
3、bash是如何匹配对应的PATH的?
我们在上面可以看到PATH不是只有一条路径而是有很多路径的,那如何去匹配的呢?PATH是以“:”来分割不同的路径,当bash去寻找正确的路径的时候会一个个的试第一个路径找不到我们要执行的文件就会换第二个路径直到最后一个路径,如果最后一个路径也不匹配的话就会“command not found”。
二、HOME
HOME:指定用户的主工作目录(及目录)
cd ~中的~对应的解释HOME这个环境变量。
Ⅵ、环境变量相关的命令
一、echo
echo:显示某个环境变量值
方法:echo $XXX(环境变量名)
二、env
env:显示全部的环境变量
方法:env
三、export
export:设置一个新的环境变量
方法:export MYENV=“XXXX”
四、set
set:查看本地定义的shell变量和环境变量
方法:set
五、unset
unset:删除环境变量
方法:unset 环境变量名
六、environ
environ:一个全局变量指向环境变量表,environ没有包含在任何的头文件中所以要使用的时候要用extern声明。
#include<stdio.h>
2 int main()
3 {
4 extern char** environ;
5 for(int i = 0; environ[i]; i++)
6 {
7 printf("environ[%d]->%s\n", i, environ[i]);
8 }
9 return 0;
10 }
七、getenv
getenv:可以得到特定的环境变量的内容,如果找到返回一个指针这个指针指向是这个环境变量的内容,如果没有找到则会返回NULL。
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("PATH:%s\n", getenv("PATH"));
return 0;
}
Ⅶ、环境变量表具有全局特性
环境变量具有全局特性,可以被继承给子进程。
#include<stdio.h>
int main(int argc, char* argv[], char* env[] )
{
int i = 0;
for(i = 0; i<=5; i++)
{
printf("env[%d]->%s\n", i, env[i]);
}
return 0;
}
环境变量表可以通过指针的形式传递给子进程,这样就可以子进程做一些个性化的操作。