Linux:环境变量
本文介绍了Linux环境变量的概念、常见类型及获取方式。环境变量是操作系统级别的动态参数,可被所有进程访问,具有全局性。常见环境变量包括PATH(查找命令目录)、HOME(用户主目录)、SHELL(终端程序路径)等。获取方式分为终端操作和编程实现:终端可通过echo、env、printenv等命令查看;编程中C/C++可用getenv()函数或main函数的envp参数获取,Shell脚本直接使用
哈喽,编程搭子们!😜 又到了沉浸式敲代码的快乐时间~把生活调成「代码模式」,带着满满的热爱钻进编程的奇妙世界——今天也要敲出超酷的代码,冲鸭!🚀
✨ 我的博客主页:喜欢吃燃面
📚 我的专栏(持续更新ing):
《C语言》 |
《C语言之数据结构》 |
《C++》 |
《Linux学习笔记》
💖 超感谢你点开这篇博客!真心希望这些内容能帮到正在打怪升级的你~如果有任何想法、疑问,或者想交流学习心得,都欢迎留言/私信,咱们一起在编程路上互相陪伴、共同进步呀!
一.环境变量的概念
环境变量(Environment Variable)是操作系统级别的、可被所有进程(程序 / 命令)访问的动态参数。
- 可以理解为环境的动态属性,只有进程运行时才可见。
- 环境变量可以操作系统或人为修改,所以不同进程运行时的环境变量可能不同。
修改方式分「临时(快速测试)」和「永久(长期生效)」,需根据场景选择- 通常具有全局性,类似C/C++的全局变量。
二.常见环境变量
1.PATH
- 系统查找可执行命令的目录清单。输入命令时,系统会按此清单中的目录顺序查找对应可执行文件,避免输入完整路径。
:~/20260128$ $PATH
-bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin: No such file or directory
2.HOME
- 当前用户的主目录路径。是用户个人文件、配置的默认存储位置(如 Linux 的 /home/用户名,即家目录)。
3.SHELL
- 当前终端使用的 Shell 程序路径(如 /bin/bash、/bin/zsh),决定终端的命令语法、交互逻辑。
4. PWD
- 英文 “Present Working Directory” 的缩写,代表当前工作目录的路径。执行 pwd 命令即读取此变量的值。
5.OLDPWD
- 代表上一次工作目录的路径。由系统自动记录,配合 cd - 命令可快速切换回上一个目录。
三.获取环境变量
在 Linux 下,获取环境变量的方法可分为终端操作和编程实现两类。
1.终端中获取环境变量
1.1 查看单个环境变量
直接通过 echo $变量名 读取,这是最常用的方式:
# 示例:查看HOME
echo $HOME
# 示例:查看PATH
echo $PATH
1.2 查看所有环境变量
env命令:简洁列出所有环境变量(键值对形式)envprintenv命令:功能与env类似,支持直接指定变量名(等价于echo $变量名)# 查看所有环境变量 printenv # 查看单个变量(效果同echo $PATH) printenv PATHset命令:列出当前 Shell 的所有变量(包含环境变量 + 局部变量)set
1.3 查看进程的环境变量
查看正在运行的进程的环境变量(需知道进程 PID):
# 替换[PID]为目标进程的ID
cat /proc/[PID]/environ | tr '\0' '\n'
(注:/proc/[PID]/environ 中环境变量以空字符 \0 分隔,tr '\0' '\n' 用于转换为换行格式方便阅读)
2.编程中获取环境变量(以Linux例 )
2.1 C/C++
- 通过
getenv()函数(标准库<stdlib.h>):#include <stdio.h> #include <stdlib.h> int main() { // 获取HOME环境变量 const char* home = getenv("HOME"); if (home != NULL) { printf("HOME: %s\n", home); } return 0; } - 也可通过
main函数的第三个参数(envp)获取所有环境变量:#include <stdio.h> int main(int argc, char* argv[], char* envp[]) { // 遍历所有环境变量 for (int i = 0; envp[i] != NULL; i++) { printf("%s\n", envp[i]); } return 0; }
- 补充
main 函数三个参数的核心作用:
- argc:整数,记录命令行参数的总个数(包含程序名本身);
- argv[]:字符串数组,存储所有命令行参数(argv[0] 是程序名,后续是传入的参数);
- envp[]:字符串数组,存储程序启动时继承的所有环境变量(格式为“变量名=值”)。
总结:argc/argv是程序接收命令行输入的入口;envp是程序获取系统环境变量的原始方式;- 三者都是操作系统在程序启动时传递给
main函数的初始信息。
2. 2 Shell 脚本
直接使用 $变量名 读取,与终端语法一致:
#!/bin/bash
# 获取并打印HOME
echo "HOME: $HOME"
以上是 Linux 下获取环境变量的常用方法,终端操作适用于手动查看,编程方式适用于程序中动态读取配置。
四.linux下,环境变量和C/C++,进程的关系
1.基础逻辑:环境变量是「进程级」的配置,C/C++ 程序运行成进程后才关联环境变量
Linux 中环境变量不属于 C/C++ 代码本身,而是「进程的运行属性」:
- 当你编译 C/C++ 代码生成可执行文件时,环境变量仅影响编译过程(比如
PATH找编译器gcc、LD_LIBRARY_PATH找编译依赖的库),但不会被写入可执行文件; - 当你运行可执行文件(生成进程)时,操作系统会为这个进程分配一套环境变量(继承自父进程,比如终端),此时 C/C++ 进程才能访问/使用环境变量。
简单说:环境变量是进程的“运行时配置”,C/C++ 程序是“代码载体”,进程是“代码运行的实例”,环境变量绑定到进程而非代码。
2. 核心关联1:环境变量的继承(进程间的传递规则)
C/C++ 进程的环境变量遵循「父→子」继承规则:
- 父进程(比如终端)启动时,会加载自身的环境变量(来自系统配置/用户配置);
- 当你在终端运行
./a.out(C/C++ 可执行文件)时,终端作为父进程,会把自己的环境变量复制一份传给a.out对应的子进程; - C/C++ 子进程拿到的是“副本”:修改自身环境变量,不会影响父进程(终端),也不会影响其他无关进程。
举例:
- 终端(父进程)中设置
export TEST=123; - 运行 C/C++ 程序(子进程),能读到
TEST=123; - 程序中修改
TEST=456,终端里echo $TEST仍为 123。
3. 核心关联2:C/C++ 进程访问/修改环境变量的方式(接口层面)
C/C++ 标准库提供了专门接口,让进程操作自身的环境变量副本:
| 操作 | 常用接口 | 作用说明 |
|---|---|---|
| 读取单个变量 | getenv("变量名") |
从进程的环境变量副本中读取指定变量值,找不到返回 NULL |
| 修改/新增变量 | setenv("变量名", "值", 1) |
新增或覆盖进程的环境变量(第三个参数 1 表示覆盖已有值) |
| 删除变量 | unsetenv("变量名") |
从进程的环境变量副本中删除指定变量 |
| 读取所有变量 | main 函数 envp 参数 |
直接获取进程启动时继承的所有环境变量(原始数组,格式为“变量名=值”) |
| 全局环境数组 | extern char **environ |
全局变量,指向进程的环境变量数组(与 envp 等价,无需通过 main 参数传递) |
关键特点:以上操作仅作用于当前 C/C++ 进程的环境变量副本,不会修改系统/父进程的环境变量。
4.核心关联3:环境变量对 C/C++ 进程的实际影响(场景层面)
环境变量直接决定 C/C++ 进程的运行行为,常见场景:
- 查找依赖库:
LD_LIBRARY_PATH告诉 C/C++ 进程去哪里加载动态链接库(.so文件),如果路径不对,进程会提示“找不到库”; - 执行外部命令:C/C++ 进程中调用
system("ls")时,PATH决定系统去哪里找ls可执行文件; - 配置程序行为:开发者可自定义环境变量(比如
APP_ENV=dev),C/C++ 进程读取后加载不同配置(开发/生产环境),无需修改代码; - 系统级配置:
HOME告诉进程当前用户的家目录(比如程序要写入用户配置文件时),LANG决定字符编码(避免中文乱码); - 编译/运行联动:编译时
CFLAGS/CXXFLAGS环境变量可传递编译参数(比如export CFLAGS="-O2"),gcc会读取这些参数优化编译。
5.特殊场景:启动 C/C++ 进程时自定义环境变量
你可以在启动 C/C++ 进程时,临时给它指定专属环境变量(仅对该进程生效):
# 临时设置 MY_CONFIG=test,启动 ./a.out
MY_CONFIG=test ./a.out
此时 C/C++ 进程能读到 MY_CONFIG=test,但终端的环境变量中没有这个值,实现“进程专属配置”。
总结
- 环境变量是进程的「运行时配置副本」,C/C++ 程序运行成进程后,继承父进程的环境变量;
- C/C++ 可通过标准库接口读写当前进程的环境变量副本,无法修改系统/父进程的环境变量;
- 环境变量直接影响 C/C++ 进程的核心行为(找库、执行命令、加载配置等),是程序与系统交互的重要桥梁。
五.环境变量,本地变量,shell内建命令
三者属于Shell不同层级的概念:本地/环境变量是Shell存储的“数据”(键值对),内建命令是Shell自带的“指令”(可操作变量/执行功能),核心区别和关联用「数据vs指令」就能快速理解。
1. 核心三要素对比表(最直观,建议收藏)
| 概念 | 本质 | 作用范围 | 生命周期 | 核心操作命令 | 典型例子 |
|---|---|---|---|---|---|
| 本地变量 | Shell的局部数据 | 仅当前Shell会话有效 | 关闭当前终端/退出Shell即消失 | 定义:var=值 查看: echo $var/set |
name=linux age=10 |
| 环境变量 | Shell的全局数据 | 当前Shell+所有子进程有效 | 关闭终端消失(临时)/重启仍在(永久) | 定义:export 变量=值 查看: echo $var/env/printenv |
PATH=/usr/bin HOME=/home/ubuntu |
| 内建命令 | Shell自带的指令 | 随Shell生效,无“范围”一说 | Shell启动即存在,退出则失效 | 直接执行命令即可 | cd/echo/export/set/unset |
2.通俗拆解+关键区别(避坑核心)
2.1 本地变量:Shell的“私人小本本”
- 理解:只给当前终端窗口用的临时数据,其他窗口、子进程都看不到,相当于自己的私人笔记,别人拿不到。
- 关键:无需加export,直接
变量名=值定义,仅当前Shell生效,子Shell(比如执行脚本、敲bash新建Shell)无法继承。 - 实操:
test=123 # 定义本地变量,无export echo $test # 输出123,当前Shell能查到 bash # 新建子Shell echo $test # 无输出,子Shell查不到本地变量 exit # 退出子Shell unset test # 删除本地变量
2.2 环境变量:Shell的“公共通讯录”
- 理解:当前Shell共享给所有子进程的全局数据,相当于公司公共通讯录,自己和同事(子Shell/脚本/程序)都能查,是Linux最常用的变量类型。
- 关键:必须加export定义(或
declare -x),能被子进程继承,系统默认的PATH/HOME等都是环境变量。 - 实操:
export test=123 # 定义环境变量,加export echo $test # 输出123,当前Shell能查到 bash # 新建子Shell echo $test # 输出123,子Shell继承到环境变量 exit unset test # 删除环境变量
2.3 Shell内建命令:Shell的“自带工具”
- 理解:不是数据,是指令,是Shell本身内置的功能(而非系统里的独立程序),执行速度极快,核心作用是操作变量、管理Shell本身。
- 关键:
- 无独立可执行文件(用
which cd查不到路径,普通命令如ls能查到/bin/ls); - 大部分变量操作的命令(export/set/unset)都是内建命令,是操作“本地/环境变量”的工具。
- 无独立可执行文件(用
3.核心关联:内建命令是操作变量的“手”
本地/环境变量是被操作的对象(数据),内建命令是操作对象的工具(指令),三者的核心关联全靠内建命令实现:
export:内建命令,把本地变量升级为环境变量(最核心的关联);set:内建命令,查看所有变量(本地+环境),也可定义本地变量;env/printenv:内建命令,仅查看环境变量;unset:内建命令,删除本地/环境变量(通用);echo:内建命令,打印单个变量的值(本地/环境都可)。
更多推荐



所有评论(0)