【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 的工作目录不会发生改变,这显然不符合用户的使用需求,所以我们有了内建命令这样的进程执行命令,专门处理这类问题


今日分享就到这里了~

相关推荐
m0_678693333 分钟前
深度学习笔记29-RNN实现阿尔茨海默病诊断(Pytorch)
笔记·rnn·深度学习
每次的天空11 分钟前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
眠修12 分钟前
Kuberrnetes 服务发布
linux·运维·服务器
重庆小透明17 分钟前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存
好奇的菜鸟1 小时前
Docker 配置项详解与示例
运维·docker·容器
sigmoidAndRELU1 小时前
读Vista
笔记·stable diffusion·世界模型
xcs194051 小时前
集运维 麒麟桌面版v10 sp1 2403 aarch64 离线java开发环境自动化安装
运维·自动化
BAOYUCompany2 小时前
暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目
运维·服务器
Sincerelyplz2 小时前
【Temproal】快速了解Temproal的核心概念以及使用
笔记·后端·开源
超龄超能程序猿2 小时前
Bitvisse SSH Client 安装配置文档
运维·ssh·github