本文已收录至《Linux知识与编程》专栏!
作者:ARMCSKGT
演示环境:CentOS 7
环境变量这个名词大家可能很陌生,对于程序员来说,我们配置某些程序的运行环境时需要配置环境变量,例如我们配置JAVA的JDK运行环境,对于不同的版本需要手动调整环境变量,每个系统中都有环境变量,本节将针对Linux系统下的环境变量进行介绍,欢迎阅读!
环境变量概述
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 例如我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找
- 环境变量通常具有某些特殊用途,例如配置程序的运行环境,而且在系统当中通常具有全局特性
- 在Linux系统中,环境变量非常多,这些环境变量记录在一起则构成了环境变量表
- 环境变量中,是以KV键值对的方式存储每个变量,例如 USER=用户名,PWD=当前所处路径等等
- 环境变量中的每一个,都有自己的用途,有的是进行路径查找的,有的是进行身份验证的,有的是进行动态库查找的,有的是确认当前路径等待
我们可以通过以下命令查看环境变量:#格式 echo $变量名 #示例 echo $USER #打印用户名 echo $PWD #打印当前所处路径
环境变量表
查看环境变量表
在Linux系统下通过该命令查看环境变量表:
$ env
env指令会打印出系统所有用户环境变量,包括我们上面使用echo单独查询的!
而这些环境变量的存储在系统中是以指针数组的方式进行存储的:
如果我们想查看更详细的环境变量,可以使用以下命令:$ set
set命令会打印相当于env来说更多的环境变量,因为set会显示一些除用户环境变量以外的本地环境变量!
PATH环境变量
我们在Linux中通常会使用各种各样的指令进行高效的工作,其实这些指令也是一个使用C语言编写的可执行程序,存放在usr/bin/目录下:
但是我们可以发现,这些指令不需要加上 ./ 就能运行,这是因为这些程序的路径已经加入到环境变量表的PATH环境变量中了!
PATH 环境变量中有存储各种指令(程序)的路径,当我们直接输入指令时,OS会根据 PATH 提供的路径搜索程序,找到了就会直接运行对应指令(程序)
而我们自己写的可执行程序却需要加上 ./ 才能运行,因为我们自己写的可执行程序不在环境变量表中!
所以将可执行程序的路径加入PATH环境变量中就可以像指令一样执行我们自己的可执行程序!
例如ls,pwd,cat …等等!
我们在bin目录下使用 ./ 也是可以执行命令的,其他路径下不行!
我们通过which指令可以查看程序是否在环境变量中:
这些指令已经在PATH环境变量中注册了!
基于这个原理,我们可以将可执行程序移入 /usr/bin/ 目录中,也可以直接使用程序名运行!
但是/usr/bin/是系统目录,需要root权限才能操作!
这就是安装和卸载程序的原理,只不过安装程序还会向环境变量写入自己的参数方便运行;我们一般不使用这个方法,因为修改系统文件是非常危险的事;我们常用的方法是修改环境变量!
修改环境变量
修改本地环境变量
我们可以直接通过命令修改环境变量!
环境变量表具有全局属性,所有程序共享,但是如果我们只想拥有单独的环境变量,可以设置本地环境变量:#我们可以直接在命令行以KV的方式定义本地环境变量 #格式 $ 变量=参数 #例如 $ MYENV=668
#格式 $ unset 环境变量名 #例如 $ unset MYENV
修改环境变量表
修改环境变量表中的环境变量,使用以下指令:
#修改环境变量格式 $ export 变量=参数 #直接修改此环境变量,覆盖以前的参数 #追加环境变量参数 $ export 变量=$变量:参数 #追加环境变量参数,不会在原有的基础上进行添加
#示例 $ export PATH=/home/ARMCSKGT/演示文件夹 #覆盖修改 $ export PATH=$PATH:/home/ARMCSKGT/演示文件夹 #追加修改
覆盖式修改环境变量会重置里面的参数,以前的环境参数全部失效;添加环境变量后我们自己的可执行程序可以直接运行,但我们不建议这样做,一般我们使用追加式的修改!
注意:
进程获取环境变量
系统在调用可执行程序时会向main主函数传递三个参数:
- int argc:传入程序的选项参数(例如ls -a),包括 ./程序
- char* argv[]:选项参数表,由bash生成,作为参数传递给main函数
- char* envp[]:环境变量表参数
– 之所以说环境变量表具有全局性是因为main函数可以通过这种方式获取环境变量表且环境变量是可以被相关的子进程继承下去的,所以环境变量具有全局性!
函数参数获取
//读取查看可执行程序选项参数: int main(int argc,char* argv[],char* envp[]) { //根据上面的规则,我们既可以使用argc参数也可以使用NULL规则结束打印 for(int i = 0;i<argc;++i) cout<<argv[i]<<endl; cout<<endl; for(int i = 0;argv[i];++i) cout<<argv[i]<<endl; return 0; }
//查看环境变量表 int main(int argc,char* argv[],char* envp[]) { for(int i = 0;envp[i];++i) cout<<envp[i]<<endl; return 0; }
系统参数获取
当然,除了给主函数传参的方法,系统库中还有另一种方法,通过二级指针的方式将环境变量表发送给进程:
#include
#include //系统头文件 using namespace std; extern char **environ; //这个参数是在库文件中定义好的,要在别的文件使用需要参数声明 int main() { for(int i = 0;environ[i];++i) cout<<environ[i]<<endl; return 0; } 展示效果与envp相同!
系统函数查询
平时我们并不需要所有环境变量,只需要某一条环境变量,系统给我们提供了系统函数getenv()获取某一条环境变量参数信息,如果环境变量存在则返回char*参数信息,否则返回控NULL!
#include
#include using namespace std; int main() { char str[64] = {0}; cout<<"请输入环境变量名:"; cin>>str; const char* envstr = getenv(str); if(envstr) cout<<str<<":"<<envstr<<endl; else cout<<"环境变量不存在!"<<endl; return 0; }
简易带选项小deom
#include
#include #include using namespace std; int main(int argc, char* argv[], char* envp[]) { //首先进行身份检验 if(strcmp(getenv("USER"), "ARMCSKGT") != 0) { cout << "当前用户为:" << getenv("USER") << "不是本人!" <<endl; return -1; } //确保选项只有一个 if(argc != 2) { cout << "指令错误,请重新输入!" << endl; cout << argv[0] << " -[a | b | c]" << endl;//提示正确使用方法 return -2; } //验证成功后,进行选项分流 if(strcmp(argv[1], "-a") == 0) cout << "执行 a 任务" << endl; else if(strcmp(argv[1], "-b") == 0) cout << "执行 b 任务" << endl; else if(strcmp(argv[1], "-c") == 0) cout << "执行 c 任务" << endl; else { cout << "指令错误,尝试重新输入" << endl; cout << argv[0] << " -[a | b | c]" << endl;//提示正确使用方法 } return 0; }
Linux环境变量到这里就介绍的差不多了,相信环境变量的介绍揭开了大家心中关于Linux的部分迷惑,我们的可执行程序为什么不能直接运行,系统指令的选项功能等等,通过环境变量大家一定有了部分了解,Linux之路还没有结束,进程的知识才刚刚开始,下一节我们继续攀登!
本次
如果文章中有瑕疵,还请各位大佬细心点评和留言,我将立即修补错误,谢谢!
其他文章阅读推荐
Linux<进程初识> -CSDN博客
Linux<进程状态及优先级> -CSDN博客
C++-CSDN博客
C++-CSDN博客
欢迎读者多多浏览多多支持!