王美洁

1.7 环境变量

1. 什么是环境变量?

你可以先把环境变量理解成:系统和 shell 在运行程序时会参考的一组名字和值。

如果你写过代码,可以先把它类比成一组系统层面的全局变量。

它们描述的不是某一个命令本身,而是当前运行环境的一些公共信息。很多程序在启动时,都会顺手去读这些变量。

例如:

bash
export                  # 输出所有的环境变量
echo $HOME              # 当前用户家目录
echo $SHELL             # 当前使用的 shell
echo $OMP_NUM_THREADS   # 线程数设置
echo $PATH              # 命令搜索路径

所以更一般地说,环境变量可以用来表达很多东西,比如:

  • 当前用户的家目录
  • 当前使用的 shell
  • 命令应该去哪里找

2. 最重要的环境变量 PATH

其中最常见、也最重要、也是你最早会反复遇到的一个例子,就是 PATH

  • 它是在告诉 shell 去哪些目录里找命令
  • 它不是程序本身,而是一组“查找规则”

很多同学刚开始会觉得 cdlspython 这些命令,好像就是“直接输入就能运行”。

但更本质地说,这些命令实际上都对应着系统里的某个位置。比如:

bash
which ls    #  ls 命令实际来自哪里
/usr/bin/ls

这其实就是 ls 命令在系统里的一个实际路径。也就是说,从最底层来说,系统真正执行的并不是一个抽象的 ls 这个词,而是某个具体路径下的可执行文件。

如果每次都让你手动输入这种绝对路径,当然也能运行,但会非常麻烦。 所以就有了 PATH 这样的环境变量。你可以先把它理解成:

  • 预先告诉 shell 几个常用目录
  • 以后你只输入命令名
  • shell 就会按顺序去这些目录里找同名程序

当你在终端里输入:

bash
echo $PATH   # 查看 PATH 环境变量的值(变量展开)
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin  # 这里 : 用以连接不同的路径

shell 并不是“天然知道”这些命令在哪里。它会去 PATH 这个环境变量列出的目录里,按顺序查找同名可执行文件。

所以:

  • 如果程序装了,但它所在目录不在 PATH 里,就会提示 command not found
  • 如果同一个命令有多个版本,PATH 的顺序也会决定优先用哪一个

3. 怎么设置环境变量?

当前 session 临时生效

最常见的写法是:

bash
export OMP_NUM_THREADS=4  # 给当前 shell 设置环境变量
export PATH=$PATH:/your/path

这类设置有一个很重要的特点:

  • export 是把变量导出到子进程(不加 export 只在当前 shell 内有效)
  • PATH=$PATH:/xxx 是在原有路径后追加(不要覆盖)
  • 关闭终端后,这些设置就没了

所以它适合临时测试,或者只想对当前这一次运行生效。

只对单条命令生效

有时你不想改整个终端环境,只想让某个变量只影响这一条命令,可以写成:

bash
OMP_NUM_THREADS=4 python run.py # 只对这一条命令生效

这个写法在提交脚本、测试不同线程数时很常见。

永久生效

如果你希望每次打开终端都自动带上这些设置,就要写到 shell 的配置文件里。

常见位置包括:

  • ~/.zshrc
  • ~/.bashrc
  • ~/.bash_profile

你具体该改哪个,取决于你使用的 shell。Mac OS 默认是 zsh,很多服务器默认还是 bash

例如:

bash
echo 'export MY_CODE=/home/user/code' >> ~/.zshrc
echo 'export PATH=$HOME/software/bin:$PATH' >> ~/.zshrc
source ~/.zshrc # 重新加载配置文件,让修改立刻生效

这里补充一下 source vs bash 的区别

bash
source script.sh   
bash script.sh
  • bash script.sh:在子 shell中执行脚本,不影响当前环境
  • source script.sh:在当前 shell 中执行脚本,会改变当前环境(变量、PATH 等)

bashzsh 和这些配置文件是什么关系?

你可以先把 bashzsh 理解成不同的 shell,也就是不同的命令行解释器(类似 python)。

它们都负责:

  • 读取你输入的命令
  • 解析并执行命令
  • 加载各自对应的配置文件

最常见的对应关系可以先这样记:

  • zsh 常看 ~/.zshrc
  • bash 常看 ~/.bashrc
  • ~/.bash_profile 更常出现在登录 shell 场景

所以要把环境变量写到对应的文件里。

如果你不确定自己现在在用什么 shell,可以先看:

bash
echo $SHELL # 查看当前用户默认 shell

4. 新手最常见的环境变量问题

1. command not found

最常见原因:

  • 程序根本没装
  • 程序装了,但目录不在 PATH
  • 你改了配置文件,但没有重新加载

可以这样查:

bash
which python
which jdftx
echo $PATH

2. 同一个命令调到了错误版本

比如你以为自己在用 conda 里的 Python,结果实际调用的是系统自带的 Python。

这时先看:

bash
which python
which pip
echo $PATH

很多问题不是“环境坏了”,而是路径顺序不对。

3. 终端里能用,脚本里不能用

这是因为脚本运行时拿到的环境,未必和你手动登录后的交互式 shell 完全一样。

比如:

  • 你把变量写在了本地终端配置里,但远程批处理脚本没有加载
  • 你在命令行里 source 过某个环境,但提交脚本里没有这一步

所以以后如果遇到“终端里能跑,作业里不能跑”,环境变量就是第一批要检查的对象。