news 2026/10/23 3:05:34

Linux(16):环境变量入门——PATH、HOME 与程序运行环境

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux(16):环境变量入门——PATH、HOME 与程序运行环境

在终端中直接输入ls就能执行命令,而当前目录中的程序通常需要写成./env_demo。程序也能读取HOME、PATH等信息,而不必每次都通过命令行参数传入。

这些现象与环境变量有关。本文整理环境变量的表示、PATH 查找、Shell 变量与 export,以及 C 程序读取环境的方法;虚拟内存和地址空间留到后续讨论。

一、环境变量是什么

环境变量是进程运行环境中的一组名称与值,常见表示形式为:

名称=值 HOME=/home/learner PATH=/usr/local/bin:/usr/bin:/bin

它们向程序提供配置和运行背景。不同程序关注的变量不同,不是设置任意名称后,所有程序就会自动产生相应行为。

环境属于具体进程。父进程可以把环境传给新启动的程序,但这不意味着所有进程实时共享同一张环境变量表。

二、命令行参数与环境变量

二者都能把信息传给程序,但用途和传递方式不同。

./env_demo-ahello

这次启动的参数可以通过argc、argv读取:

intmain(intargc,char*argv[]){for(inti=0;i<argc;++i)printf("argv[%d]=%s\n",i,argv[i]);return0;}

此处是函数片段,使用时需要包含<stdio.h>。对于上面的命令,通常有:

argc=3 argv[0]=./env_demo argv[1]=-a argv[2]=hello

argv[argc]是空指针。-a的功能不是 main 自动赋予的,而要由程序解析并实现。

环境变量则是另一组输入,例如程序通过getenv("HOME")获取目录配置,无需把 HOME 的值每次写成位置参数。

Linux 中还常见带第三个环境参数的 main 写法,但它不是 ISO C 通用的 main 形式。本篇使用标准的 main 形式,配合 getenv 或 Linux/POSIX 环境中的 environ,不将“main 最多有三个参数”作为通用语言规则。

三、PATH:不写完整路径时,去哪里找程序

查看当前 Shell 的 PATH:

echo"$PATH"

PATH 是由冒号分隔的目录列表。假设它是:

/usr/local/bin:/usr/bin:/bin

当 Bash 需要查找一个不带/的外部命令时,会利用 PATH。忽略命令缓存等细节后,搜索顺序可以用下面的图理解:

是

否

是

否

查找不带斜杠的外部命令

检查 /usr/local/bin

找到可执行文件?

执行找到的程序

检查 /usr/bin

找到可执行文件?

继续检查 /bin 等后续目录

找到则执行,否则报告未找到

图只描述外部命令的 PATH 搜索。别名、函数和 Shell 内建命令等有自己的处理规则,不能把每条 Shell 命令都当作磁盘上的独立程序。

为什么要写 ./env_demo

./env_demo已经包含/,表示使用当前目录下的指定路径,不再依靠 PATH 搜索这个名字。

如果当前目录不在 PATH 中,只输入env_demo,即使文件就在眼前,也可能提示命令未找到。找到了文件,还需要满足执行权限等条件;PATH 不会绕过权限检查。

不建议为了省略./就把.放进 PATH,尤其不要放在搜索列表前面,以免在不可信目录中误执行同名程序。

若确实需要加入自己的工具目录,可保留原有 PATH 并追加:

exportPATH="$PATH:$HOME/bin"

前提是这个目录中确实有需要运行、且具有执行权限的程序。不要直接覆盖原有 PATH,否则可能使常用外部命令无法按名字找到。

四、常见变量与查看方式

名称常见用途注意事项
PATH外部命令的搜索目录不等于动态库搜索路径
HOME用户主目录与当前工作目录不同
PWDShell 维护的当前工作目录信息程序需要可靠获取工作目录时可使用 getcwd
USER用户名相关信息不能单凭它进行可靠的身份认证
SHELL通常记录用户的登录 Shell 路径不保证就是此刻执行命令的 Shell

查看单个值:

echo"$HOME"echo"$PWD"

查看传给外部程序的环境:

env

实际输出与用户和会话有关。环境中可能包含令牌、代理地址等敏感信息,不宜把完整 env 输出原样发布到博客。

五、Shell 变量与 export

在一个新的 Bash 终端中,用一个未使用的练习变量名操作:

LEARN_ENV_DEMO=helloecho"$LEARN_ENV_DEMO"env|grep'^LEARN_ENV_DEMO='

赋值时等号两边不要加空格。普通 Shell 变量可以由当前 Shell 使用,但在没有导出属性时,不会作为环境变量传给普通外部程序。

接着导出:

exportLEARN_ENV_DEMOenv|grep'^LEARN_ENV_DEMO='

此时新启动的外部程序可以收到这项环境信息。也可以把赋值与导出合在一起:

exportLEARN_ENV_DEMO=hello

删除练习变量:

unsetLEARN_ENV_DEMO

export 是 Shell 内建命令,修改的是当前 Shell 的变量导出属性,不是创建一张所有进程共享的全局表。

六、环境怎样传给子进程

启动时传递环境

启动时传递环境

不会反向修改

父 Shell:export LEARN_ENV_DEMO=hello

子程序 A:收到 hello

子程序 B:收到 hello

A 修改自己的环境

B 的环境不因此改变

父 Shell 的环境仍保持原值

这是一张传递关系图,不表示所有程序共享同一块环境内存。fork 时子进程继承环境;执行新程序时,环境由启动方提供,通常包含导出的变量,也可以被显式增删。

父 Shell 后来修改变量,不会自动同步给已经运行的子进程;子程序修改自己的环境,也不会反向改掉父 Shell 的变量。

因此,有时所说的环境变量“全局性”,应理解为它可以沿进程启动关系被继承和使用,而不是全系统实时共享。

七、C 程序读取环境

1. getenv:按名称读取

保存为env_demo.c:

#include<stdio.h>#include<stdlib.h>intmain(void){constchar*names[]={"HOME","PATH","LEARN_ENV_DEMO"};for(size_ti=0;i<sizeof(names)/sizeof(names[0]);++i){constchar*value=getenv(names[i]);printf("%s=%s\n",names[i],value?value:"(not set)");}return0;}

编译、运行:

gcc-Wall-Wextraenv_demo.c-oenv_demo ./env_demoexportLEARN_ENV_DEMO=hello ./env_demounsetLEARN_ENV_DEMO

若练习变量原先未设置,第一次运行预期显示(not set),导出后重新启动程序则可以读到 hello。这是代码分析得到的预期现象,不是实际运行日志。

getenv找不到名称时返回 NULL;空字符串则表示变量存在但值为空,二者不能混为一谈。不要直接把可能为 NULL 的返回值交给%s。接口细节见 getenv 手册。

还可以只给这一次程序启动提供变量:

LEARN_ENV_DEMO=once ./env_demo

这种写法不把这个临时值永久留在当前 Shell 中。

2. environ:遍历环境

在 Linux/POSIX 环境中,可以通过 environ 遍历环境字符串:

#include<stdio.h>externchar**environ;intmain(void){for(char**entry=environ;*entry!=NULL;++entry)puts(*entry);return0;}

每个元素指向一条名称=值字符串,指针数组以 NULL 结束。调试时可以在自己的终端观察,但不要把完整输出直接公开。

USER 等变量由运行环境提供,也可能被人为修改。读取用户名作演示可以,不能把字符串比较当作真正的权限控制。

八、临时生效与配置文件

终端里的赋值和 export 默认只影响当前 Shell 及其后续启动的程序,不会自动写入配置文件。

若需要在后续会话中设置变量,Bash 常见的相关文件包括~/.bashrc和~/.bash_profile,但它们分别何时读取,与登录方式、是否交互及发行版配置有关,不能把两者当成无条件同时执行的文件。

本篇练习不要求修改系统配置,也不需要 root。先掌握临时设置、读取、继承和 unset,再按实际需求决定是否持久化。

九、复习要点

  • argv 接收命令行参数,环境变量提供另一组运行配置。
  • PATH 控制不带路径的外部命令搜索;./程序指明当前目录下的路径。
  • Shell 变量不一定被导出,export 决定它是否进入后续程序的环境。
  • 环境可以继承,但不是父子进程间实时同步的共享表。
  • getenv 按名读取,environ 可以遍历;读取时注意 NULL 和敏感信息。
  • 本次设置与持久化配置是两回事,不能把 USER 当作可靠认证依据。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 3:05:02

slam十四讲-ch1

slam十四讲-ch1 文章目录slam十四讲-ch1前言一、SLAM是什么&#xff1f;二、如何使用这本书1. 数学基础篇2. SLAM 技术篇课本代码前言 slam14讲作为很多slamer的入门书籍&#xff0c;第一节内容主要回答如下两个问题。 其一&#xff1a;SLAM是什么&#xff1f;其二&#xff1…

作者头像 李华
网站建设 2026/10/23 3:04:00

c++11进阶学习 第二部分

1&#xff1a;lambda表达式lambda表达式定义了一个匿名函数&#xff0c;并且可以捕获一定范围内的变量。lambda表达式的语法形式简单归纳如下&#xff1a;[capture](params) opt -> ret {body;};其中capture是捕获列表&#xff0c;params是参数列表&#xff0c;opt是函数选项…

作者头像 李华
网站建设 2026/10/23 3:03:40

边缘AI进入建筑后,WiFi Halow技术帮集成商搞定带宽、距离和功耗

边缘AI正在改变数据在建筑里的流动方式&#xff0c;让建筑变得越来越智能。视频监控能实时认出人、车辆和异常活动&#xff1b;门禁系统能把身份验证、数据分析和自动反应结合起来&#xff1b;空调和供暖系统会根据房间里有没有人来调节能耗&#xff1b;环境传感器能在空气质量…

作者头像 李华
网站建设 2026/10/23 3:03:24

地址输入提示接口实战:从敲第一个字到选中地点的完整接入

摘要&#xff1a;电商下单页、外卖收货地址、物流寄件表单——凡是需要用户填写地址的场景&#xff0c;都少不了"输入提示"&#xff08;也叫地址联想、地址自动补全&#xff09;。本文以丰图地址输入提示API为例&#xff0c;给出一个可直接改造的前端接入方案&#x…

作者头像 李华
网站建设 2026/10/23 3:03:19

前端通用组件开发全指南|从 0 到 1 打造稳定可复用的业务组件

适合 Vue / React 开发者&#xff0c;面向 B 端后台系统&#xff08;跨境、ERP、SaaS 场景&#xff09;&#xff0c;兼顾设计原则、避坑经验&#xff0c;附思维导图要点&#xff0c;适合技术博客发布很多团队都会踩同一个坑&#xff1a;业务写着写着&#xff0c;到处是重复弹窗…

作者头像 李华