实用指南:【Linux系统】—— 环境变量

news/2025/10/15 10:17:02/文章来源:https://www.cnblogs.com/slgkaifa/p/19142711

实用指南:【Linux系统】—— 环境变量

【Linux系统】—— 环境变量

  • 1 概念介绍
  • 2 命令行参数
    • 2.1 main 函数有参数吗?
    • 2.2 argc 与 argv
    • 2.3 命令如何通过不同参数实现不同子功能
  • 3 环境变量:PATH
    • 3.1 查看环境变量
    • 3.2 将路径添加进 PATH 中
  • 4 环境变量从哪里来
    • 4.1 从存储的角度理解环境变量
    • 4.2 环境变量最开始从哪来
  • 5 认识更多环境变量
  • 6 对环境变量的操作
    • 6.1 导入环境变量
    • 6.2 删除环境变量
    • 6.3 通过代码的方式获得环境变量
      • 6.3.1 main函数参数获取环境变量
      • 6.3.2 getenv 函数获取环境变量
      • 6.3.3 全局变量 environ 获取环境变量
  • 7 本地变量

1 概念介绍

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 如:我们在编写 C/C++ 代码的时候,在链接的时候,从来不知道我们所链接的动静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

2 命令行参数

2.1 main 函数有参数吗?

  问大家一个问题:main 函数有参数吗?

int main()
{
return 0;
}

  好像我们平时写的 main函数 都是不用传参的,但不传参就代表不用参数吗?

main函数 至少有两个参数int argcchar *argv[]

int main(int argc, char *argv[])
{
return 0;
}

main函数 仅仅是我们自己的代码的入口,实际上 main函数 也要被其他函数(Linux中为 _start 函数)调用

2.2 argc 与 argv

  现在我们知道 main函数 有两个参数 argcargv,他们是什么呢?有什么用呢?

argc 是 指针数组 argv 的长度
  我们将 argv 的内容打印出来看看

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


运行:

在这里插入图片描述


  我们发现argv:其实就是将命令以空格作为分隔符,一个一个放入指针数组中

在这里插入图片描述

  我们在命令行中写的命令会被当成一个长串字符串,有人帮我们将命令以空格作为分隔符进行切分,被切分后的各个字符即命令行参数。将命令行参数依次放入 argv数组 中,数组中有多少个参数由 argc 指明。同时有效元素放完必须以NULL结尾

2.3 命令如何通过不同参数实现不同子功能

  看到这里,不知道大家有没有想到什么?
  我们平时用的命令,他们本质上就是可执行程序,且一般是由 C语言 写的。我们可以在后面带命令行选项ls -a -l中的 -a-l。我们输入不同的选项,命令可以执行不同的子功能。如果做到的呢?不急,我们先写一段代码

#include <stdio.h>#include <string.h>int main(int argc, char *argv[]){if(argc != 2){printf("Usage:%s [-a|-b|-c]\n", argv[0]);return 1;}const char *arg = argv[1];if(strcmp(arg, "-a") == 0)printf("这是功能1\n");else if(strcmp(arg, "-b") == 0)printf("这是功能2\n");else if(strcmp(arg, "-c") == 0)printf("这是功能3\n");elseprintf("Usage:%s [-a|-b|-c]\n", argv[0]);return 0;}

  代码逻辑:如果未带选项或者选项错误,打印提示信息;否则执行对应子功能

在这里插入图片描述

  所以:命令行参数是为了让一个程序可以通过选项实现不同的子功能。这也是指令选项的实现原理!
:./code 也算一个命令行参数,所以判断语句是 if(argc != 2) 而不是 if(argc != 1)

  谁帮我们进行切分的呢?是shell,Linux 中即 bash

  为什么我们之前不用带命令行参数呢?因为不需要。我们之前写的代码功能就一个,如果我们想让我的代码有不同的子功能就可以带命令行参数

  所以在进程启动时,有一张表 —— argv表,用来支持实现选项功能。

3 环境变量:PATH

  我们发现,执行我们指令的程序需要带 「./」,而执行系统的命令就不需要带 「./」。这是为什么呢?

  无论是我们自己写的程序还是系统的指令,没有本质区别,都是二进制程序。那为什么一个要带路径一个不用呢?
  虽然不知道为什么,但有一点我们清楚:要执行一个程序,必须先找到他!

  正因为要找到它,所以我们运行自己的程序要带「./」表明是在当前路径。我们执行系统命令就不用呢?原因是系统中存在环境变量 PATH,来帮助系统找到目标二进制文件。

  环境变量 PATH 默认情况下在系统中存在,用来标识一串路径,以用来告诉系统去那些路径下找二进制文件

3.1 查看环境变量

  怎么查看PATH环境变量呢?

  在系统中,查看所有环境变量
  使用指令:env

在这里插入图片描述

  环境变量也是一个变量,环境变量的构成:名称=内容

只想看指定环境变量的内容:
  使用指令:echo $环境变量名称

在这里插入图片描述

  我们发现 PATH 中的内容都是以绝对路径的形式呈现,以 : 作为分隔符
  当我们输入 ls 等指令,系统不是直接去 /usr/bin 路径去查;而是依次遍历所有路径,最终在 /usr/bin 路径下找到 ls 指令。如果将所有路径遍历完依然没找到,就会报 Command not found。

3.2 将路径添加进 PATH 中

  我们将自己当前的路径添加到 PATH 中,那我们写的 code 可执行也可以不带「./」直接就能被系统找到。
  如何将路径添加进 PATH 中呢?
  PATH 已经是一个变量,我们直接对其赋值

在这里插入图片描述

  这样我们的指令就能不带 「./」 直接被系统找到了

  但是,系统的指令找不到了

在这里插入图片描述

  原因是刚刚我们 PATH=/home/gy/lesson13覆盖式的写,将 PATH 中原来的路径覆盖了

在这里插入图片描述

  怎么改回来?不用担心,PATH是一个内存级的变量,想恢复只需重新登录账号即可。

  如何追加式的将路径写入PATH呢?如下图:

在这里插入图片描述

  当然,如果再退出后登录,PATH 依然恢复默认值

4 环境变量从哪里来

4.1 从存储的角度理解环境变量

  环境变量是由名称和内容组成的,那环境变量是由谁来保存的呢?答案是 bash

  当我们一旦登录时,系统就会给我们创建一个 bash 进程。bash 从系统中读取所有的环境变量信息,然后在 bash 内部形成一张表 —— 环境变量表。环境变量表和上面的 argv 一样都是指针数组。上述所查看的所有环境变量名称=内容都是一个个字符串,环境变量表指向这一个个字符串

  我们输入的指令如:ls -a -b 首先是被 bash 拿到,bash将 ls -a -b拆分成 ls-a-b,构建一张命令行参数表。后拿着 ls 这个命令,在环境变量表中找到 PATH,再在 PATH 中的各个路径找 ls。所以指令的查找工作是由 bash 自己完成的

  结论:bash 内部会有两张表:命令行参数表和环境变量表

4.2 环境变量最开始从哪来

  我不登录不就没有 bash 了吗?那环境变量最开始从哪来呢?
环境变量是从系统相关的配置文件来。

bash 最开始启动时,会从配置文件中读取多有环境变量的信息,并在自己内部创建环境变量表

  这个配置文件怎么看?

vim .bash_profile
vim .bashrc
vim /etc/bashrc

在这里插入图片描述

  我们登录时,bash 就会被创建。bash 就会读取 .bashrc.bash_profile 配置文件的内容构建出环境变量表。
  如果我们在配置文件中加入自己的路径,那么以后登录,我们的 code 就能不带路径自动被执行。

  如果 Linux 中有 10 个用户登录,系统中就存在 10 个 bash。是不是意味着这 10 个 bash 每一个都要从配置文件中奖将环境变量读到自己的 bash 上下文中?所以每一个 bash 中都存在两张表:命令行参数表和环境变量表

5 认识更多环境变量

  每一个环境变量都有其特定的功能,下面我们介绍几个

  • HOME:当前用户的家目录

在这里插入图片描述


  • SHELL:当前用户登录时,用的是哪一个版本的 shell。默认保存的是 bash 的路径(/bin/bash)

在这里插入图片描述


  • USER:当前用户

在这里插入图片描述


  • HISTSIZE:记录最大历史命令个数

在这里插入图片描述


  • PWD:当前的工作路径

在这里插入图片描述


  • OLDPWD:记录上一次所处的工作路径

在这里插入图片描述

  所以为什么 cd - 可以做最近两次路径的切换?环境变量给我们提供好了

6 对环境变量的操作

前文,我们已经学会了两个获取环境变量的方法

6.1 导入环境变量

导入环境变量:
  使用指令:export 要导入变量名=要导入变量内容

export MYENV=11223344

在这里插入图片描述

  不知大家有没有觉得奇怪
  环境变量是在谁的上下文中的?是 bash。而 export 是命令,是一个由 bash 创建的子进程。进程之间是互不影响的。所以为什么在进程 export 中的操作会影响进程 bash 呢?会改变父进程的环境变量表呢?

  只有一个解释:export 命令是一个内建命令
内建命令不需要创建子进程,由 bash 自己亲自执行。一般是由 bash 调用函数或者系统调用完成

6.2 删除环境变量

删除环境变量:
  使用指令:unset 环境变量名

unset MYENV

在这里插入图片描述

6.3 通过代码的方式获得环境变量

6.3.1 main函数参数获取环境变量

  main函数有参数吗?有!
  main函数最多有几个参数?
3个!

  那还有一个参数是谁呢?
  最后一个是 char *env[]

int main(int argc, char *argv[], char *env[])
{
return 0;
}


char *env[]是什么呢?
char *env[] 是一个指针数组,未来父进程 (如:bash) 可以把环境变量表传给 main 函数,由 char *env[] 接收。环境变量表与命令行参数表的形式是一模一样的,最后都以NULL结尾

  我们写一段代码验证一下

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

(void)argc;的写法是为了不让编译器报警告。在 gcc 中如果我们定义了变量确不去用他会报警告,将其强转表示使用了 argc 变量,就不会报警告

在这里插入图片描述

  此时 main函数 就获取了环境变量,这个环境变量是谁的呢?是父进程也就是 bash 的。

  结论:环境变量可以被子进程继承。环境变量在系统中具有全局特性


:Linux 中 main 函数是由 _start 函数调用的,_start 会先扫描 main 函数的参数个数,再执行相应 main函数。大致如下:

_start
{
int ret = 0;
int arg_count = 0;
//扫描 main 函数的参数个数
arg_count = 0/2/3;
if(arg_count == 0)
ret = main();
else if(arg_count == 2)
ret = main(argc, argv);
else
ret = main(argc, argv, env);
}

6.3.2 getenv 函数获取环境变量

  输入指令:man 3 getenv 查看 getenv 函数

在这里插入图片描述

getenv:

  • 函数功能:获取一个环境变量的内容。获取成功返回内容的其实地址;否则返回NULL


代码实验:

#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[], char *env[]){(void)argc;(void)argv;(void)env;char *value = getenv("PATH");if(value == NULL)return 1;printf("PATH->%s\n", value);return 0;}

在这里插入图片描述


  如果我只想让我写的程序只能我执行,就算 root 也没门,该怎么设计?
  我们可以运用环境变量。
  整个系统只有一个人知道登录用户是谁:bash。在 bash 中的环境变量表中记录着环境变量 USER,而 bash 可以将环境变量交给子进程,子进程可以根据环境变量进行身份识别

#include <stdio.h>#include <string.h>#include <stdlib.h>int main(int argc, char *argv[], char *env[]){(void)argc;(void)argv;(void)env;char *who = getenv("USER");if(who == NULL)return 1;if(strcmp(who, "gy") == 0)printf("这是程序正常执行逻辑\n");elseprintf("只有 gy 能执行\n");return 0;}

  为什么全局变量要有全局特性呢?
  因为这样子进程就可以将环境变量继承下去,子进程就可以结合环境变量做个性化操作。比如上面指定一个只能直接执行的程序。

6.3.3 全局变量 environ 获取环境变量

  输入指令:man environ 全局变量 environ
environ 指向环境变量表

在这里插入图片描述

  为什么 environ 是 char** 类型的,因为environ指向的是环境变量表,而环境变量表本身就是一个指针数组

:使用 environ 之前,需将其声明

#include <stdio.h>#include <unistd.h>extern char **environ;int main(int agrc, char *agrv[]){(void)agrc;(void)agrv;int i = 0;for(; environ[i]; ++i){printf("environ[%d]->%s\n", i, environ[i]);}return 0;}

在这里插入图片描述

  上述三种获取环境变量的方法中,我们最常用的是第二种,因为法一和法三都是获取整张环境变量表,而法二获取的是单个环境变量的内容。

7 本地变量

先看操作:

在这里插入图片描述

  如上图,我们可以直接在命令行中定义变量,我们将这个变量称为本地变量

  此时我们用 env 查看环境变量,发现并没有找到 i 变量。这也说明我们定义的 i 变量不是环境变量

查看本地变量:
  使用指令:set

set 可以查看本地变量和环境变量

在这里插入图片描述

删除本地变量:
  使用指令:unset 本地变量名

  所以什么是本地变量呢?
本地变量不会被子进程继承,只会在 bash 内部被使用。





好啦,本期关于 环境变量 的知识就介绍到这里啦,希望本期博客能对你有所帮助。同时,如果有错误的地方请多多指正,让我们在 Linux 的学习路上一起进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/937310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 年 MBR 膜厂家最新推荐排行榜:权威评选优选品牌,污水处理设备选型指南全解析污水处理设备MBR膜厂家推荐

当前我国水污染治理进入攻坚阶段,市政污水、工业废水与农村污水排放量持续攀升,MBR 膜作为污水处理核心设备,其性能直接决定处理效率与水质达标率。但市场中品牌超 50 家,产品质量、抗污染能力与服务水平差异显著,…

统一管理第三方包的依赖包版本号

起因 在java项目中,我在maven的pom.xml中引用了io.github.officiallysingh:spring-boot-starter-spark:1.3包,然后这个包里又有org.apache.spark:spark-core_2.13:3.5.5包的引用,而在spark-core_2.13包中又引用了or…

主线程阻塞型帧堆积(Frame Backlog)

“主线程阻塞型帧堆积(Frame Backlog)” 是前端性能调优中一个非常核心但常被忽视的现象,尤其在 WebGL / Three.js / 游戏循环 或 高频 UI 渲染 场景下。 🧠 一、定义:什么是“主线程阻塞型帧堆积” 帧堆积(Fra…

图像去雾算法详解与MATLAB实现

多种图像去雾算法的完整MATLAB实现,包括经典的暗通道先验方法和基于深度学习的方法。 图像去雾概述 图像去雾旨在从雾天拍摄的退化图像中恢复清晰图像,改善图像质量和可视性。 经典去雾算法 1. 暗通道先验去雾算法 f…

ROS 传感器模块的通用架构设计与跨中间件扩展实践

在汽车智能化浪潮下,传统CAN总线已难以支撑自动驾驶海量数据传输需求。本文深入解析车载以太网如何通过高带宽、低延迟特性突破这一瓶颈,重点剖析其在自动驾驶系统中的TSN实时传输、SOME/IP服务通信等核心技术优势!…

替代传统FTP的系统:企业数字化转型新选择

传统FTP系统在国产化适配、数据安全、传输效率等方面存在明显短板,已难以满足企业数字化转型需求。新一代文件传输系统通过全生态信创适配、国密算法加密、智能压缩算法及权限矩阵管理,有效解决了明文传输、管理低效…

算法设计与分析作业

字节跳动代码规范 字节跳动的代码规范核心是追求极致效率和保障大规模协作。 它并不仅仅是代码格式那么简单,而是一套覆盖整个开发流程的准则。 • 可读性第一:代码是写给人看的,其次才是给机器执行的。命名清晰、结…

需求分析论

找角色:人、系统 找名词:划分到各系统类 找实体:名词抽象,细化属性 找关系:实体关系,关联、聚合、组合 找动词: 识别实体方法 找服务类:识别领域服务,聚合一组聚合根实体交互 流程交互:服务类关系调用,同步…

2025年叠螺机/加药装置/输送机厂家最新权威推荐榜:专业制造与高效输送系统综合解决方案

2025年叠螺机/加药装置/输送机厂家最新权威推荐榜:专业制造与高效输送系统综合解决方案随着工业环保要求的不断提高和自动化生产需求的持续增长,叠螺机、加药装置和输送机作为环保处理和物料输送的核心设备,在市政污…

2025年书包柜厂家最新推荐排行榜,学生书包柜,员工书包柜,更衣柜储物柜,智能书包柜公司口碑之选

2025年书包柜厂家最新推荐排行榜,学生书包柜,员工书包柜,更衣柜储物柜,智能书包柜公司口碑之选随着教育现代化进程的不断推进和企事业单位对员工福利重视程度的提升,书包柜行业迎来了全新的发展机遇。从传统的学生…

2025.10.14 刷题

2025.10.14 刷题1. P7738 [NOI2021] 量子通信 由于给了字符串生成器,所以串随机 根据鸽笼原理,把串分成 16 块,由于 \(k \le 15\) ,所以必有一个块不变 枚举这个块,然后期望有 \(\frac{n}{2^{16}} \approx 7\) 个…

企业高效数据传输:数据摆渡解决方案全解析

企业在跨网络传输数据时,常面临安全风险与效率低下的双重挑战。传统FTP或移动硬盘传输缺乏加密,易导致数据泄露;而部分定制化方案成本高、实施周期长,中小企业难以承受。数据摆渡解决方案通过整合加密传输、身份认…

别再空谈数据价值!制造业如何用主数据管理 “抠” 出千万级成本?

凌晨三点,某汽车零部件厂的仓库还亮着灯 —— 管理员老张蹲在堆积如山的纸箱前,翻着皱巴巴的账本叹气:“这批不锈钢螺丝去年进了5000个,现在还剩3000个没动,再过半年就过期了,又要当呆滞料处理……” 而办公室里…

2025.10.13 测试

2025.10.13 测试1. U612392 追忆 是一个小技巧 考虑在序列中尽量向前匹配,在那个位置计数 然后发现要求是对于一个元素,在其前面的元素与其之间的空隙不能有这个字符 所以可以枚举结尾位置 通过 $\sum _{i = 0}^n \b…

2025年注塑加工行业优质企业最新推荐排行榜:助力需求企业精准筛选可靠合作伙伴

当前,注塑加工行业在现代制造业中地位关键,广泛服务于汽车、电子、家电、医疗等众多领域,行业规模不断扩大,但也面临原材料价格波动、市场竞争激烈、环保标准趋严等挑战。需求企业在选择注塑加工合作伙伴时,常因信…

2025 年工程管理软件平台公司最新推荐榜:聚焦数字化效能,优选靠谱服务商

随着 “数字中国” 战略深化及《“十四五” 建筑业发展规划》推进,建筑行业数字化转型进入加速期,工程管理软件已从大型房企专属工具逐步普及至地产开发、建筑施工、交通基建等多个领域。2025 年建筑业信息化市场规模…

2025 年工程管理软件平台公司最新推荐榜:聚焦数字化效能,优选靠谱服务商

随着 “数字中国” 战略深化及《“十四五” 建筑业发展规划》推进,建筑行业数字化转型进入加速期,工程管理软件已从大型房企专属工具逐步普及至地产开发、建筑施工、交通基建等多个领域。2025 年建筑业信息化市场规模…

被 Excel 格式折腾的那些瞬间---excl格式转换

​做数据岗这些年,光跟 Excel 格式转换打交道就占了不少工作时间:领导要 Word 版的报表摘要,得手动复制粘贴还总乱格式;财务要加密的 PDF 账单,转完发现公式全丢了;批量处理旧版 XLS 文件时,挨个另存为 XLSX 能…

阵列信号处理中的盲源分离算法

盲源分离(Blind Source Separation, BSS)是阵列信号处理中用于从混合观测信号中恢复源信号的重要技术。 盲源分离基础理论 问题模型 阵列信号盲源分离的数学模型为: X(t) = A S(t) + N(t)其中:X(t) = [x₁(t), x₂(…

标准版v9.0破解版及软件安装包

程序名称:金蝶KIS标准版V9.0 发版日期:2011年10月17日 网盘地址:迅雷下载 123网盘下载程序说明:本安装包为官方安装包,由第118楼资源网收集上传分享,内含许可说明,比较经典的一款财务软件,网上资源比较少,…