看懂什么是环境变量

程序能跑,常常不是因为「装上了」,而是操作系统和进程约定了一套键值:可执行文件在哪些目录、JDK 在哪、代理是谁。这套由操作系统维护、子进程继承的命名变量,就是 环境变量。配不好时,双击图标没事,终端里却报「不是内部或外部命令」——差的就是这份约定。

什么是环境变量

操作系统本身是大型程序,Windows、Linux、macOS 都是。JDK、MySQL、Chrome、微信等应用跑在操作系统之上。

环境变量是操作系统(以及当前进程)用来描述运行环境的命名变量。 名字唯一,值是一段字符串。操作系统自己读,当前进程里启动的应用程序也能读到(子进程默认继承父进程的环境)。

部分软件装完必须再配环境变量才能在终端里当命令用,典型是 JDK、MySQL:除了把安装目录下的 bin 加进 PATH,还常要设 JAVA_HOME 这类「告诉别的程序去哪找我」的变量。

系统变量与用户变量

图形界面里常见两类,日常说「配环境变量」指的就是它们:

  • 系统变量:整台机器、所有用户都能读。改它需要管理员权限。
  • 用户变量:只对当前登录用户生效,账号之间互相隔离。

这是 Windows 注册表里的分法。Unix、macOS 没有同名的两栏,对应关系是:写在 /etc 下的对全体用户生效,写在家目录(~/.zshrc 等)里的只对当前用户生效。

为什么要配环境变量?

启动程序常见两种方式:双击图标、在终端里敲命令。

  • 桌面快捷方式里已经写了程序的完整路径,系统按路径去执行。
  • 终端里只敲命令名(如 java)时,系统必须知道磁盘上哪一个文件对应这个名字。三种写法都能跑:
# 完整绝对路径
/usr/bin/java -version

# 先进入程序所在目录(Unix 下当前目录通常不在 PATH 里,仍建议写 ./java)
cd /usr/bin
./java -version

# 只敲命令名,靠 PATH 查找
java -version

没有把 Java 的 bin 写进 PATH 时,直接敲 java -version 会提示找不到命令:系统不知道可执行文件在哪。不配 PATH 也能运行,但每次都要写完整路径。

PATH 怎么查找

PATH 是最常用的环境变量,值是一串目录,专门存放「可以当命令执行的程序」所在的文件夹。

敲一条 没有写路径 的命令时:

  • Unix、macOS:PATH 里登记的目录 从左到右 查找,找到第一个同名可执行文件就停。 默认不会先搜当前工作目录(除非 PATH 里显式写了 .)。当前目录里的脚本应写成 ./script.sh
  • Windows(cmd): 会先在当前目录找,再按 PATH 里的目录找。这是和 Unix 不同的一点。

目录之间的分隔符:Unix、macOS 用冒号 :,Windows 用分号 ;

查看 PATH:

echo $PATH
echo %PATH%

查找某个命令实际对应哪个文件:

# Unix、macOS
which java
command -v java
type java
where java

系统推荐的 macOS 改 PATH 方式:不要直接改 /etc/paths(系统更新会覆盖)。在 /etc/paths.d/ 下新建文件(例如 mypath),每行一个目录,由 path_helper 在登录 Shell 时拼进 PATH。这是给 全机 加路径的做法;个人目录写进 ~/.zprofile 即可。

当前终端临时追加(关掉窗口即失效):

export PATH=/example/bin:$PATH

环境变量配置文件在哪?

Shell 在不同场景下读取不同文件,理解这一点是正确配置环境变量的关键。

读取机制:

  • Linux /etc/environment:由 PAM 的 pam_env 模块在登录时读取,内容是 KEY=VALUE 列表,不是 Shell 脚本。macOS 不使用此文件。
  • macOS path_helper:登录 Shell 会自动执行 /usr/libexec/path_helper(bash 通过 /etc/profile,zsh 通过 /etc/zprofile),它读取 /etc/paths/etc/paths.d/ 来拼接系统 PATH。
范围 bash zsh(macOS Catalina 起默认)
系统级 /etc/profile/etc/bashrc /etc/zprofile/etc/zshrc
用户级 ~/.bash_profile~/.profile~/.bashrc ~/.zprofile~/.zshrc

加载顺序(bash)

  • 登录 Shell:先读 /etc/profile,再依次尝试 ~/.bash_profile~/.bash_login~/.profile(只读第一个存在的)。
  • 交互式非登录 Shell:读 /etc/bashrc~/.bashrc

macOS Terminal 默认启动的是登录 Shell。若只改 ~/.bashrc 而不在 ~/.bash_profilesource 它,新窗口的环境变量将不生效。

加载顺序(zsh)

  • 登录时:读 /etc/zprofile~/.zprofile
  • 交互时:读 /etc/zshrc~/.zshrc

PATH 建议写在 ~/.zprofile~/.zshrc(均在 path_helper 之后执行)。不要写在 ~/.zshenv 中,否则会抢在 path_helper 前执行,导致 PATH 顺序被打乱。

系统级追加(Linux)

Linux 的 /etc/profile 会自动载入 /etc/profile.d/*.sh。如需系统级配置,请在此目录下新建脚本,不要直接修改 /etc/profile 本体。

GUI 程序例外

从 Dock 或 Spotlight 启动的 GUI 应用不会读取任何 Shell 配置文件(它们走的是 launchd 启动路径)。

终端中生效的环境变量,图形界面应用不一定有——这属于启动机制不同,不是配置错误。

macOS、Linux 配置环境变量

查看

# 当前进程的环境变量(export 出去的)
printenv
env

# 当前 Shell 的变量,范围比环境更大
set

printenv PATH
echo $PATH
echo ${PATH}

临时(只在当前窗口)

关掉终端、新开窗口都会丢掉:

export MY_NEW_VAR="example"
echo $MY_NEW_VAR

永久

写入配置文件,再 source 该文件,或新开终端、重新登录。

系统级(全体用户,需要管理员权限)。能不改 /etc/profile 就不要改:

sudo vim /etc/profile

# 文件内写入
export MY_NEW_VAR="example"

source /etc/profile

当前用户,bash:

vim ~/.bash_profile

export MY_NEW_VAR="example"

source ~/.bash_profile

当前用户,zsh(现行 macOS 默认):

vim ~/.zprofile

export MY_NEW_VAR="example"

source ~/.zprofile

交互式相关的别名、提示符也可以写在 ~/.zshrc

删除(当前会话)

unset MY_NEW_VAR

unset 不会改配置文件;永久删除要把文件里对应的 export 行去掉后再 source

Windows 配置环境变量

图形界面里同时能改系统变量和用户变量:系统属性 → 高级 → 环境变量(运行 sysdm.cpl 也可打开)。永久生效 以这种配置方法为准。

下面命令默认指 cmd。PowerShell 语法不同:读是 $env:PATH,会话内写是 $env:MY_NEW_VAR="example"

查看全部:

set

查看单个(例如 PATH):

set PATH

会话内临时设置,关掉该 cmd 窗口即失效,不会写入系统保存的环境变量:

set MY_NEW_VAR=example

set PATH=%PATH%;C:\example\bin

清空当前窗口的 PATH(只影响这个会话):

set PATH=

set 全部是会话级。新开的 cmd 读的是图形界面(或 setx)里存下来的那份。已经打开的窗口不会自动刷新,要关掉重开。

环境变量是进程启动时拷贝的一份表。PATH 可以少写绝对路径;JAVA_HOME 一类则把位置告诉别的程序。改之前分清:临时还是永久、用户还是系统、以及当前这个终端会不会把值传给它拉起的子进程。

参考资料

environ(7) — Linux 手册

path_helper(8) — macOS

Windows 环境变量

© lizhao all right reserved,powered by Gitbook文件修订时间: 2026-09-02 21:05:06

results matching ""

    No results matching ""