目录
一. 环境变量的基本概念
1.1 什么是环境变量
1.2 环境变量的功能测试
二. 与环境变量相关的操作
三. 环境变量的组织方式
四. 通过代码获取环境变量的值
五. 总结
环境变量是用于指定操作系统相关参数的、全局的变量。通过env指令,可以查看系统中全部的环境变量。
下面是几个常见的环境变量:
查看环境变量值的方法:echo $环境变量名
环境变量有如下几点特性:
PATH表示指令的默认搜索路径,我们首先通过echo $PATH,获取当前的PATH值,如图1.1所示,我们看到所有的路径被:分割,OS会依次从PATH的路径中搜索用户输入的指令,直到找到指令为止,如果到了最后一个路径还没有找到,那么OS就认为指令不存在,无法执行。
我们创建编译下面的代码,生成可执行程序mytest.exe,分别在命令行中输入./mytest.exe和mytest.exe,前者成功运行,后者运行失败,详见图1.2。这是因为mytest.exe并不是一条指令,mytest.exe文件所在的路径不包含在PATH值内。
结论:Linux系统内置的指令不需要路径,输入指令名称就可以运行。用户自主编译生成的可执行程序,需要加上路径./XXX才可以运行。
接下来,通过指令 export PATH=$PATH:(pwd) 修改修改环境变量PATH的值,然后再次在命令行中直接输入mytest.exe,可见这次程序运行成功了(详见图1.3)!此时通过echo $PATH查看PATH的值,可见当前路径被加入到了PATH中,因此直接输入mytest.exe可以成功运行程序。
在两个终端下,分别使用普通用户zhangHHH和root用户登录,分别使用echo $HOME指令在不同用户登录的情况下查看环境变量HOME的值,可以看到HOME就是用户的家目录。
语法:echo $val_name,可以输出环境变量的值。这里的$不能省略,如果省略,那么输出的就是环境变量本身了,如echo PATH输出PATH。
语法:export 环境变量名称=值,如:export VAL=1234,就定义了一个名称为Val,值为1234的环境变量,这个变量具有全局属性。
如果我们通过export设定了环境变量,那么使用env同样能够查到。
语法:unset [环境变量名称]
语法: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来获取记录选项的个数。
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;
}
变量char **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;
}
语法: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;
}
补充知识:
我们可以直接在命令行中使用 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;
}