Linux环境变量详解

server/2024/12/22 15:26:29/

文章目录


1. 前言

本篇文章将以PATH环境变量为例来对整个Linux环境变量进行学习理解。

本文着重讲解了什么是PATH环境变量、如何添加PATH环境变量、系统中的其他环境变量环境变量的由来、环境变量的基本操作以及命令行参数中环境变量的体现。

2 什么是PATH环境变量

Linux中的各种指令本质上是/usr/bin/目录下的一个个可执行程序,和我们自己编写的可执行程序没有任何区别:

在这里插入图片描述

但是我们发现,执行我们自己的程序时需要指定路径,但是执行Linux中的各种指令却不需要指定路径:

在这里插入图片描述

这是因为系统中存在PATH环境变量,PATH中存放着这些指令的地址。当我们使用这些指令时,系统会自动去PATH中寻找对应指令,如果找到了就执行,找不到就报错command not found

3. 如何添加PATH环境变量

我们可以使用echo $PATH来查看PATH环境变量中包含的内容:

在这里插入图片描述

注:PATH中不同路径之间用:分割。

我们也可以通过向PATH中添加内容来让我们自己的程序可以不需要指定路径就能被执行

==法一:==直接将程序添加到/usr/bin/目录下(不建议使用这种方法,因为我们写的程序没有经过测试,容易污染指令池)。

在这里插入图片描述

==法二:==使用export命令将当前可执行程序的路径导入到PATH中。

在这里插入图片描述

法二相关说明:

  1. 其中的$PATH代表之前PATH中内容,:之后的为新添加的内容。注意不要直接export PATH=/home/czh/practice,这样会把之前的PATH覆盖掉,使得Linux中的各种指令必须指定路径使用。
  2. PATH中不能由空格,因为Linux中以空格为分隔符。
  3. 使用export命令声明,变量只在**当前的shell(BASH)或其子shell(BASH)**下是有效的,在关闭shell后失效,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。

4. 系统中的其他环境变量

PATH环境变量只是系统中众多环境变量的一种,除了PATH,我们还有许多其他环境变量,且不同的环境变量有不同的功能,也适用于不同的场景,比如:

  • HOSTNAME:主机名
  • USER:当前用户名
  • PWD:当前系统路径
  • HOME:当前用户的家目录
  • HISTSIZE:shell能记忆的最多历史命令的条数

在这里插入图片描述

我们可以使用env命令来查看系统中所有的环境变量

在这里插入图片描述

5. 环境变量的由来

ls -al /home/czh可以发现家目录下存在两个隐藏文件.bash_profile.bashrc

在这里插入图片描述

实际上,当我们在登录shell时,操作系统会让我们当前的shell进程执.bash_profile中的内容,而.bash_profile又会调用执行.bashrc,它们会将对应的环境变量导入到shell进程的上下文环境中。所以,如果我们上面不小心将$PATH覆盖掉了也不用担心,重新登录shell就好了。

至此,环境变量的定义如下:

环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量,这些变量往往具有特殊功能,且能够一直被bash以及bash的子进程访问。

注:环境变量具有全局属性的根本原因是环境变量会被子进程继承。

6. 环境变量的基本操作

6.1 设置环境变量

Linux命令行其实是可以定义变量的,但是以这种方式定义出来的变量是本地变量,即只在bash进程中有效,而不是环境变量,因为环境变量具有全局属性:

在这里插入图片描述

我们可以使用export直接定义环境变量,也可以使用它将已存在的本地变量导为环境变量

在这里插入图片描述

我们可以使用set命令来查看所有变量,包括环境变量和本地变量;使用 unset 来取消变量,包括环境变量和本地变量:

在这里插入图片描述

6.2 通过getenv获取环境变量

我们可以使用echo $环境变量来获取特定的环境变量,也可以通过getenv()函数来获取环境变量

在这里插入图片描述

其中name是我们要获取的环境变量的名称,如果获取成功就返回该环境变量的具体内容,失败就返回null

有了getenv函数后,我们就可以自己编写系统中的某些指令了,比如pwd

#include <stdio.h>
#include <stdlib.h>#define MYPWD "PWD"int main()
{char* env = getenv(MYPWD);printf("%s\n", env);return 0;
}

在这里插入图片描述

6.3 环境变量的应用场景

我们上面提到,环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量。其中PATH是为了满足我们指令路径搜索的需求,而除了指令需求之外还有许多其他需求,其中非常重要的一个就是身份认证

我们以一个例子说明:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define USER "USER"int main()
{char* who = getenv(USER);if(strcmp(who, "root") == 0){printf("Operation success!\n");}else {printf("Permission denied!\n");}return 0;
}

在这里插入图片描述

注:这里要使用su -,而不能使用su,因为su -会重新登录shell,此时shell会重新加载环境变量,让$USERczh变为root,而su只是把用户身份切换为root

我们可以在程序内部通过getenv函数来获取当前的Linux用户,然后判断其是否具备某种权限,再执行对应操作,另外,我们还可以通过stat来获取一个文件的其他属性,比如读写执行等,然后根据这些属性判断一个用户是否能对该文件进行操作:

在这里插入图片描述

7. 通过命令行参数获取环境变量

我们上面提到,程序可以通过getenv函数来获取环境变量,其实除了getenv函数,程序还可以通过命令行参数传递来获取环境变量

学过C语言的同学应该都知道,main函数其实是有参数的,且这些参数通过命令行传递:

int main(int argc, char* argv[], char* env[]);

其中argv是一个指针数组,数组里面的每一个元素都指向一个字符串,argc用来指定数组元素的个数;它们配合使用可以实现类似于ls -a -l -d选项的功能。

而指针数组env就是用于接受父进程传递过来环境变量的参数,我们可以通过在main函数中打印env中的内容来验证它:

#include <stdio.h>
#include <stdlib.h>int main(int argc, char* argv[], char* env[])
{int i = 0;for(i=0; env[i]; i++){printf("env[%d]:%s\n", i, env[i]);}return 0;
}

在这里插入图片描述

程序也可以通过环境表environ来获取环境变量

环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串,每个进程都会收到一张环境表:

在这里插入图片描述

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char* argv[], char* env[])
{extern char** environ;int i = 0;for(i=0; environ[i]; i++){printf("%d:%s\n", i, environ[i]);}return 0;
}

在这里插入图片描述

注:environ是一个全局的外部变量,所以切记使用前要用extern关键字进行声明,然后再使用。



http://www.ppmy.cn/server/41653.html

相关文章

go语言基础2

1.基本数据类型 Go语言是一种强类型的静态编译语言&#xff0c;类型是高级语言的基础&#xff0c;有了类型&#xff0c;高级语言才能对不同类型抽象出不同的运算。 Go语言内置七类基本数据类型&#xff08;20个具体子类型&#xff09;。 布尔类型&#xff1a;bool 整型&#xf…

RK3568平台开发系列讲解(SPI篇)spi_dev 驱动分析

🚀返回专栏总目录 文章目录 一、结构体二、API三、spidev驱动分析3.1、init3.2、probe3.3、spidev_write3.4、spidev_read3.5、spidev_open四、spi_register_driver分析五、spi_dev缺点沉淀、分享、成长

Mirror从入门到入神

Mirror从入门到成神 文章目录 Mirror从入门到成神简介NetworkClientRegisterPrefabConnect (string address)Disconnect ()activeactiveHost NetworkServerSpawn 简介 Mirror是一个unity网络同步框架&#xff0c;基于MonoBehaviour生命周期的回调的基础上进行数值的同步&#…

【计算机毕业设计】基于SSM++jsp的高校专业信息管理系统【源码+lw+部署文档+讲解】

目录 第1章 绪论 1.1 课题背景 1.2 课题意义 1.3 研究内容 第2章 开发环境与技术 2.1 MYSQL数据库 2.2 JSP技术 2.3 SSM框架 第3章 系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 系统流程 3.2.1 操作流程 3.2.2 登录流程 3.2.3 删除信息流…

Intel HDSLB 高性能四层负载均衡器 — 快速入门和应用场景

目录 文章目录 目录前言与背景传统 LB 技术的局限性HDSLB 的特点和优势HDSLB 的性能参数基准性能数据对标竞品 HDSLB 的应用场景HDSLB 的发展前景参考文档 前言与背景 在云计算、SDN、NFV 高速发展并普遍落地的今天&#xff0c;随着上云业务的用户数量越来越多、数据中心的规模…

vue + element-plus 开发中遇到的问题

1.问题之路由守卫 初写路由守卫&#xff0c;对于next()的理解不是很透彻&#xff0c;就想着都放行&#xff0c;不然看不到效果&#xff0c;结果控制台出现了警告&#xff0c;想着报黄的问题就不是问题&#xff0c;但仔细一看发现他说&#xff0c;如果再生产阶段就会失败&#x…

面向对象的三大特性是什么?

面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;是现代软件开发中的核心范式之一&#xff0c;其核心概念在于将现实世界的事物抽象为“对象”&#xff0c;并通过类和对象之间的交互来实现复杂的功能。面向对象的三大特性包括&#xff1a;封装&#xff0…

8数据通信名词解释

目录 数据通信&#xff1a; 信号&#xff1a; 信源&#xff1a; 信宿&#xff1a; 信道&#xff1a; 三种通信方式&#xff1a;单工&#xff0c;半双工&#xff0c;全双工 数据传输方式&#xff1a; 传输模式&#xff1a;同步传输和异步传输 码元&#xff1a; 数字通信…