【Linux】环境变量


个人主页~


环境变量

1、基本概念

环境变量是操作系统用来存储和传递关于系统环境信息的一种机制 ,它相当于一种全局变量,可供系统中的各个程序、进程在运行时访问和使用,这些信息包括系统的配置参数、文件路径、用户设置等,程序可以根据这些环境变量的值来确定如何运行,例如在哪里查找文件、使用什么语言设置、分配多少内存等

2、常见环境变量

PATH:指定命令的搜索路径

HOME:指定用户的主工作目录

SHELL:当前使用的shell名称

通过echo $NAME指令可以查看当前系统环境变量,NAME是环境变量的名称

3、相关指令

指令 作用
echo 显示某个环境变量值
export 设置一个新的环境变量
env 显示所有环境变量
unset 清除环境变量
set 显示本地定义的shell变量和环境变量

4、PATH的相关概念

创建一个hello world的c文档,生成可执行文件,我们输入两条指令,分别是直接写process和./process,我们发现./process能执行文件

我们在《打破Linux神秘的面纱》一文中提到过,process的写法是指令写法,而指令就是存储在bin目录下的可执行程序,我们可以通过root账户将可执行程序移动到bin目录下,就可以形成人造指令,在《从软件到硬件了解进程》一文中提到过./是定位目录,因为进程属性有一条就是current work dir 当前工作目录(cwd),那么我们可以得出一个结论,指令的进程属性中的cwd指向的就是bin目录,而我在这里又会提供一个结论:环境变量PATH中的分隔符是: ,分隔符两边的是目录,而且都是bin目录,PATH当中的文件不需要定位目录就可以执行

那么我们通过指令export PATH=$PATH:程序所在目录对环境变量进行增加,我们就可以直接process执行程序了,这个是一个临时的改变,在我们重启Shell软件后就恢复如初了,要想永久改变,我们可以做以下步骤:

第一种:编辑/etc/profile文件(对所有用户生效):

①打开终端,使用文本编辑器(如vim或nano)编辑/etc/profile文件,以vim为例,在终端输入sudo vi /etc/profile

②在文件末尾添加export PATH=$PATH:新路径,例如export PATH=$PATH:/home/user/mybin,保存并退出编辑器

③在终端执行source /etc/profile使设置立即生效

第二种:编辑用户主目录下的.bashrc文件(仅对当前用户生效):

①打开终端,使用文本编辑器编辑.bashrc文件,如vi ~/.bashrc

②在文件末尾添加export PATH=$PATH:新路径,保存并退出编辑器

③执行source ~/.bashrc使设置立即生效

5、环境变量的组织方式

环境表:每个程序运行时都会收到一张环境表,它是一个字符指针数组,数组中的每个指针都指向一个以'\0'结尾的环境字符串

environ 变量:environ是一个char**类型的全局外部变量,指向环境变量表,它没有包含在任何头文件中,在代码中使用时需要用extern声明,如extern char **environ; ,通过它可以第三方形式获取所有环境变量

getenv 函数:char *getenv(const char *name)函数可通过指定的环境变量名称来获取其对应的值,该函数包含在头文件<stdlib.h>中,比如获取PATH环境变量的值就用char*s = getenv("PATH");

6、通过代码获取环境变量

(一)命令行第三个参数

我们要学习通过命令行第三个参数获取环境变量就要先了解main函数的三个参数,我们在之前使用main函数的时候一般都是如下所示

c 复制代码
int main(void)
{
	//...
	return 0;	
}

其实main函数一共最多是有三个参数的,如下所示

c 复制代码
int main(int argc, char *argv[], char *envp[])
{
	//...
	return 0;	
}

其中argc是命令行参数的数量argv是一个指向命令行参数字符串的指针数组,用于存储命令行参数envp是一个指向环境变量字符串的指针数组 ,用于传递程序运行时的环境信息




在我们程序当中,我们可以通过strcmp的方式来进行选项的应用,如果我们想要-a选项的效果是打印hello world,-b选项的效果是打印hello linux,我们可以这样写

c 复制代码
for(int i = 0; i < argc; i++)
{
	if(strcmp(argc[i],"-a") == 0)
	{
		printf("hello world");
	}
	if(strcmp(argc[i],"-b") == 0)
	{
		printf("hello linux");
	}
	//...
	else
	{
		printf("wrong!!!");
	}
}

通过envp打印环境变量

(二)第三方变量environ

environ是一个库中定义的全局变量,指向环境变量表,没有包含在任何头文件中,所以在使用的时候要用extern声明

7、环境变量全局性的验证

c 复制代码
int setenv(const char *name, const char *value, int overwrite);
//name:这是一个指向字符串的指针,代表你要设置的环境变量的名称

//value:同样是一个指向字符串的指针,表示你要赋给环境变量的值

//overwrite:这是一个整数类型的参数,用于控制是否覆盖已存在的同名环境变量
//若为0,当环境变量已经存在时,不会对其进行修改,不存在时创建并设置它
//若为非0,无论该环境变量是否已经存在,都要将其值更新为value

这个程序如果父子进程都打印出TEST_VARIABLE: test_value那么就说明子进程可以继承父进程的环境变量

以上我们所运行的进程,都是bash的子进程(bash就是命令行解释器,所有我们所创建的进程的父进程或祖宗进程),bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我们的环境变量

8、本地变量

和环境变量不同,本地变量只在本bash内部有效,不会被继承,通过MYENV="内容"定义本地变量名和内容,在子进程中不可被访问

我们知道我们在命令行(bash)中所创建的进程都是命令行(bash)的子进程,所以我们的本地变量是没办法在这种进程中显示的,只有将它export进环境变量,才可以被命令行子进程访问

9、内建命令

Linux中命令分为普通命令和内建命令,普通命令是要通过bash创建子进程完成的,而内建命令bash自己亲自执行,bash不创建子进程,相当于bash调用自己内部的函数

常见的内建命令有echo,cd等

若echo是外部命令,那么在输出本地变量SUPER值的时候是访问不到的,因为echo会产生一个子进程,命令行子进程访问不到本地变量,不符合用户使用需求

若 cd 是外部命令,在执行时,Shell 会创建一个子进程来运行它,子进程拥有独立的环境和工作目录,当子进程修改工作目录时,这种修改仅局限于子进程自身,并不会对父进程(即当前的 Shell 进程)的工作目录产生影响,也就是说,执行完外部的 cd 命令后,当前 Shell 的工作目录不会发生改变,这显然不符合用户的使用需求,所以我们有了内建命令这样的进程执行命令,专门处理这类问题


今日分享就到这里了~

相关推荐
F——10 分钟前
云计算行业分析
运维·学习·云计算·边缘计算
HaoHao_01021 分钟前
AWS Fargate
大数据·服务器·云计算·aws·云服务器
Channing Lewis25 分钟前
Linux 中为什么进程是休眠的,但是还是处理了数据
linux·运维·服务器
程序员yt26 分钟前
‌双非硕士的抉择:自学嵌入式硬件开发还是深入Linux C/C++走软开?
c++·嵌入式硬件·学习·计算机网络
深度Linux39 分钟前
Linux性能优化实战,网络丢包问题分析
linux·性能优化·linux内核
赶紧写完去睡觉43 分钟前
尚硅谷课程【笔记】——大数据之Shell【二】
大数据·linux·shell编程
激进的猴哥1 小时前
day33-数据同步rsync
linux·运维·服务器
Sean_summer1 小时前
2.5学习
学习
kfepiza1 小时前
for fn in *.html ;do fns=“${fns} ${fn} “ ;done; firefox ${fns}
linux·html·firefox
似霰1 小时前
Unix/Linux编程:fcntl函数总结
linux·unix