✅<1>主页::我的代码爱吃辣
📃<2>知识讲解:Linux——环境变量
☂️<3>开发环境:Centos7
💬<4>前言:环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
目录
一.基本概念
二.Linux系统中常见的环境变量
1.查看指定的环境变量
2.PATH
3.HOME
4.SHELL
三.环境变量的组织方式
四.添加环境变量
五.环境变量的继承
六.获取环境变量
1.命令行第三个参数
2.通过第三方变量environ获取
3.通过系统调用获取或设置环境变量
一.基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
查看当前LInux系统的环境变量:
指令:
env
windows下的环境变量:
环境变量本质就是一种变量,一种K/V的对用关系,由变量名和变量值。
二.Linux系统中常见的环境变量
1.查看指定的环境变量
echo $NAME #NAME:环境变量名称
例如:
2.PATH
指定命令的搜索路径.
- 我们平时写的一些C/C++代码,编译成可执行程序以后,通过 ./ 运行,本质是告诉操作系统可执行程序的位置。
- 但是系统自带的指令,本质也是C语言写的程序,为什么系统的指令不需要指定路径呢?
- 就是因为环境变量PATH里面存储了指定命令的搜索路径。
3.HOME
指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)。
当我们每次登录系统的时候,系统就会记录下登录用户,并且填充HOME环境变量,并且创建bash进程帮我们执行 cd /home/XXX 的命令,进入我们自己的家目录,这就是我们为什么一进入系统,默认就在自己的家目录里。
普通用户:
root用户:
4.SHELL
当前Shell,它的值通常是/bin/bash。
三.环境变量的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串,表的最后一个位置是NULL。
四.添加环境变量
我们刚刚介绍了PATH环境变量,指定命令的搜索路径.那么我们可不可以将自己写的可执行程序的查询路径也添加进PATH里,这样我们的可执行程序,也可以实现不需要 ./ 就可以直接执行了。
测试代码:test.c
#include <stdio.h>
#include <unistd.h>
int main()
{
int n = 3;
while (n)
{
printf("原神启动:%d\n", n);
sleep(1);
n--;
}
}
makefile:
ttest:test.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -rf ttest
方法一:
使用export将我们该可执行程序的路径导入PATH中,后续可以不用加 ./ 就可以直接运行可执行程序,因为操作系统可知直接通过环境变量中的地址找到可执行程序。
export PATH=路径
注意:
这样会有一个很尴尬的问题就是我们的PATH中只有这一个路径了,即之前的TATH环境变量中的其他路径被我们导入的路径覆盖了。
我们这样导入环境变量:
export PATH=$PATH:路径
方法二:
将可执行程序拷贝到 /usr/bin目录下,/usr/bin目录就是系统默认的命令存储的路径。
sudo cp ./ttest /usr/bin
本质将可执行程序放进/usr/bin目录下的过程,就是软件安装的过程。
上述这种添加变量的方式,就是将命令添加到系统环境中,还有一种添加变量的方式是将变量添加到本地,这种变量我们称之为本地变量。
例如:
hello=100
这就是添加了一个本地变量。
五.环境变量的继承
- 环境变量是可以被子进程继承的。
- 我们使用 export 导入的进程,就可以使用 echo 命令查询得到,echo 本质也是一个程序,之所以echo 可以查询到我们导入bash的环境变量本就是,echo 继承了bash的环境变量。
- 但是仅仅只是环境变量可以被子进程继承,本地变量是不可以子进程继承。
六.获取环境变量
1.命令行第三个参数
我们先看看命令行参数:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < argc; i++)
{
printf("%s ", argv[i]);
}
printf("\n");
return 0;
}
注意:
- argv是一个指针数组,数组每一个元素都是一个char*,每一个char*都指向了一个字符串。
- argc是argv数组的元素个数。
注意:
- argv数组存储的就是我们命令行输入的以空格为分隔的字符串。
- 顺序是从左往右
命令行的第三个参数:
测试代码:
#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;
}
运行结果:
注意:
- env也是一个指针数组,每一个数组元素存储的就是一个环境变量。
- 证明了环境变量是可以被子进程继承的。
- 应证了环境变量的组织方式。
2.通过第三方变量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;
}
运行结果:
注意:
- libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
3.通过系统调用获取或设置环境变量
系统调用:
getenv()
getenv参数是环境变量名,返回的是环境变量值字符串,如果没找到对应的环境变量,就返回NULL。
测试代码:
[wq@iZuf6hzw565sb02fomef99Z 23_9_12]$ HELLO=100#本地变量
[wq@iZuf6hzw565sb02fomef99Z 23_9_12]$ export MYHELLO=100#环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
if (getenv("PATH"))
{
printf("PATH:%s\n", getenv("PATH"));
}
if (getenv("MYHELLO"))
{
printf("MYHELLO:%s\n", getenv("MYHELLO"));
}
if (getenv("HELLO"))
{
printf("HELLO:%s\n", getenv("HELLO"));
}
return 0;
}
注意:
- 环境变量通常具有全局属性,可以被子进程继承下去。
- 我们之前说过本地变量不会被子进程继承,上面的代码也可以看出来。
- 但是为什么使用命令echo就可以查询到本地变量?因为echo是内建命令。