环境变量
一般是指操作系统用来指定操作系统运行环境的一些参数。
例如:当我们再写c/c++代码时,我们并不知道库在哪里,程序链接时却能知道库在哪里并且链接。这是因为有相关环境变量帮助编译器进行查找。
环境变量一般除了具有某些特殊含义之外,还具有全局特性。
下面是几个Linux下常见的环境变量:
- PATH:指定命令的搜索目录
- HOME:指定用户的主工作目录
- HISTSIZE:指保存历史命令的记录条数
- SHELL:当前shell。通常是/bin/bash
- LOGNAME 当前用户的登录名
- HOSTNAME 指主机的名称
- LANGUGE 语言相关的环境变量,多语言可以修改此环境变量
- MAIL 当前用户的邮件存放目录
- PS1 基本提示符,对于root用户是#,对于普通用户是$
如何查看环境变量:
echo $NAME//NAME是你要查看的环境变量名
PATH
用如下代码测试:
#include <stdio.h>
int main()
{
printf("hello world!\n");
return 0;
}
我们运行时需要敲如下命令:
./test
但是我们平常执行其他命令时并不需要敲./,但是在运行我们自己的可执行文件时就要加上./。原因是操作系统下那些写好的我们可以执行的可执行文件都在操作系统指定好的目录下。
我们查看和搜索命令有关的环境变量—-PATH
可以看到结果是以冒号分割的若干目录,意味着在这些目录下的可执行文件可以直接执行,不需要加./当前路径。
我们很容易就能想到如果想要使我们写好的可执行文件像系统写好的文件一样直接执行,可以将我们的文件放入其中任一目录下,或是将我们写好的可执行文件的当前目录加入到以上目录中。
下面我们测试一下这两种方法。
第一种方法将我们写好的测试函数生成的可执行文件放入以上路径下任一路径下。
可以看到此时运行hello不需要在加路径了。
第二种方法是将我们当前可执行文件的路径加入到PATH环境变量的路径里。
同样,此时hello函数也可以不需要加路径就能运行了。
以上,证明了PATH这个环境变量是为了搜索系统为我们写好的可执行文件,可以使我们不加路径直接使用,所以我们写好的可执行文件与系统内的可执行文件在用途上还是有差别的,所以建议不要随意往环境变量下的路径内随意加东西。
说明:以上方法只在本终端下有效。
HOME
我们分别在用户和root用户下测试该环境变量的值
由于当前用户不同,而改变当前用户的主工作目录。
对比可以发现:~相当于$HOME
HISTSIZE
说明当前保存历史命令记录条数最大1000条。
如何获取环境变量
方法一:我们在学习main函数的参数时,就见过这个第三个参数其实就是环境变量。
#include <stdio.h>
int main(int argc,char *arv[],char *env[])
{
int i=0;
for(;env[i];i++)
{
printf("%s\n",env[i]);
}
return 0;
}
方法二
#include <stdio.h>
int main(int argc,char *arv[])
{
extern char **environ;
int i=0;
for(;environ[i];i++)
{
printf("%s\n",environ[i]);
}
return 0;
}
c库中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以要用extern声明。
方法三
通过系统调用获取环境变量
#include <stdio.h>
int main()
{
printf("%s\n",getenv("PATH"));
return 0;
}
用系统调用getenv(),putenv()来获取特定的环境变量。
环境变量的全局属性
下面来说明环境变量的全局属性,
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *env=getenv("MYENV");
if(env)
{
printf("%s\n",env);
}
return 0;
}
以上代码获取了MYENV这个环境变量,接下来查看是否有这个环境变量。
发现结果什么都没有,说明该环境变量根本不存在。
用export导出环境变量,发现此时运行有了,原因是因为环境变量具有全局属性是可以被子进程继承的。
export的作用是导出环境变量,未经过export一般称为本地变量,只在本shell有效,经过export导出就具有全局属性,可以被子进程继续继承下去,不止子进程包括子进程的子进程,像树枝结构一样,层层继承下去。