思维导图:
基本概念
环境变量一般是指在操作系统用来指定操作系统运行环境的一些参数,环境变量是在操作系统中具有一个特定名字的对象,它包含了一个或多个应用程序所将要使用到的信息.
比如当我们编写c代码,在链接的时候。从来不知道我们所连接的动态
在哪里,但是我们依然可以连接成功,产生可执行程序,原因就是有相关环境变量在帮助编译器进行查找动态链接库。
- 环境变量通常具有一些特殊用途,在系统当中具有全局特性。
查看环境变量命令
echo $(环境变量名) 查看特定环境变量
env 查看所有环境变量
expot 设置一个新的环境变量
set 查看本地定义的变量
unset 清除环境变量
Linux下的变量种类:
按变量的生存周期来划分,Linux变量可分为两类:
1.永久的: 需要修改配置文件,变量永久生效.
2.临时的: 使用export命令声明即可,变量在关闭shell时失效.
常见环境变量
“PATH”:可执行文件的查找路径。
“HOME”:指定用户的主工作目录(用户登录linux系统时,默认的目录)
“HISTSIZE”:保存历史命令记录的条数
“SHELL”:当前shell,他的值通常是/bin/bash
LANG:当前系统的语言
测试环境变量
测试”PATH”
测试代码:
#include <stdio.h>
int main ()
{
printf("hello world\n");
return 0;
}
当我们需要运行该程序,看到结果时,需要输入以下命令:
./a.out
然而,我们平常输入的命令,如”ls”,”pwd”等命令时(这些命令也是程序),并不需要敲”./”, 这是为什么?
原因是“ls”这些可执行命令是已经在操作系统中写好,都在操作系统指定的目录下,也就是路径已经确定好,当你执行命令时,操作系统就会按照指定路径生成结果。
我们可以用echo $PATH ls 查看命令的路径
[root@localhost enviroment]# echo $PATH ls
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/zyc/bin ls
可以看到结果是以冒号分割的若干目录,意味着在这些目录下的可执行文件可以直接执行。
查看一下PATH 该环境变量的路径
在当前目录下,默认的PATH的值.它表示当我们在当前目录下执行一条命令时命令的搜索路径. 每一个目录都以冒号隔开. 例如我们执行一个可执行程序xx,系统就会到这些目录下面去找,在这些目录下找到的话才执行,找不到的话就不执行.
//基于这个原理,我们也可以将自己的变量设置成环境变量。将我们写好的可执行文件放在那些特定目录下,
//方法一:将我们写好的可执行文件所在路径放入环境变量PATH下,运行
测试HOME(指定用户主工作目录)
- 在普通用户下和root用户下。分别执行 echo $HOME命令,结果如下
可以看到普通用户和超级用户主工作目录并不同
2.执行 cd ~ ; pwd, 观察与HOME 命令对应关系
从图中可以看出 ~ 和HOME有着相同的作用,都可以进入主工作目录
测试HISTSIZE(保存历史命令记录条数)
echo $HISTSIZE 查看最近使用的命令条数)
history 10 查看最近十条使用的命令具体是什么命令)
测试SHELL(显示当前shell)
设置一个新的环境变量
setenv函数
功能:添加环境变量
函数库: stdlib.h
定义格式:int setenv(const char *name, const char *value, int overwrite)
返回值:成功返回1,失败返回-1
相关函数: int unsetenv(const char *name);
只在本shell有效
export 添加环境变量
在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅及于该此登陆操作。
注意一般来说,环境变量都用大写加下划线来命名. 比如我们现在设置几个环境变量:
以看到当我第一次查看zyx这个环境变量的时候,我发现echo调用失败了, 当创建环境变量以后并给他赋值为小可爱后,再次echo查看的时候就会显示出小可爱,说明创建环境变量成功。
export设置只对当前的bash登录session有效,它是存在内存里面的。
如果想要环境变量永久生效可以修改下面两个文件中的任何一个:
1 /etc/profile
2 .bash_profile
其中,/etc/profile是全局的环境变量,对所有用户生效,而.bash_profile只对当前用户启作用。
测试set (查看本地环境变量)
从图中我们可以看到黄色部分就是我们刚刚创建的本地环境变量ZYC
unset删除一个环境变量**
我们有增,那么肯定会有删除,我们linux下删除一个环境变量的方法就是: unset + 环境变量名.
环境变量的组织方式
每个程序,系统都会给他安排一张环境表,环境表是一个字符指针数组,每个指针指向一个以” \0 ” 结尾的环境变量字符串
通过代码获得环境变量
1.通过C函数获取环境变量
命令行参数形式获取
#include <stdio.h>
int main(int argc,char* argv,char *env[])
{
int i=0;
for(;env[i];i++)
{
printf("%s\n",env[i]);
}
return 0;
}
通过第三方变量environ获取
#include <stdio.h>
int main(int argc,char* argv)
{
extern char** environ;
int i=0;
for(;environ[i];i++)
{
printf("%s\n",environ[i]);
}
return 0;
}
2.通过系统调用获得环境变量
1. putenv
通过此函数并不能添加或修改 shell 进程的环境变量,或者说通过setenv函数设置的环境变量只在本进程,而且是本次执行中有效。如果在某一次运行程序时执行了setenv函数,进程终止后再次运行该程序,上次的设置是无效的,上次设置的环境变量是不能读到的。
函数名: putenv
功能:改变或增加环境变量
表头文件 stdlib.h
定义函数 int putenv(const char * string);
函数说明:putenv()用来改变或增加环境变量的内容。参数string的格式为name=value,如果该环境变量原先存在,则变量内容会依参数string改变,否则此参数内容会成为新的环境变量。
返回值:执行成功则返回0,有错误发生则返回-1。
错误代码:ENOMEM 内存不足,无法配置新的环境变量空间。
相关函数 getenv,setenv,unsetenv
2. getenv
函数名: getenv
功 能: 从环境中取字符串,获取环境变量的值
头文件: stdlib.h
**用 法:**char *getenv(char *envvar);
函数说明:getenv()用来取得参数envvar环境变量的内容。参数envvar为环境变量的名称,如果该变量存在则会返回指向该内容的指针。环境变量的格式为envvar=value。getenv函数的返回值存储在一个全局二维数组里,当你再次使用getenv函数时不用担心会覆盖上次的调用结果。
返回值: 执行成功则返回指向该内容的指针,找不到符合的环境变量名称则返回NULL。如果变量存在但无关联值,它将运行成功并返回一个空字符串,即该字符的第一个字节是null。
相关函数:_wgetenv、getenv_s、_wgetenv_s
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n",getenv("PATH"));
return 0;
}
环境变量属性
- 全局特性
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *env=getenv("MYENV");
if(env)
{
printf("%s\n",env);
}
return 0;
}
这个程序直接查看,没有结果,说明该环境变量不存在。但是当我们导出环境变量
export MYENV="hello world"
再次运行程序,发现结果有了,
这说明:
环境变量相当于全局变量,它可以被子进程继承:父进程生成子进程是共享代码段的而数据段则相互独立,当生成子进程时会继承父进程的环境变量,否则无法知晓系统的一些变量、PATH,动态连接库的路径、语言环境等;