Linux: 环境变量与 PATH——配置开发环境

环境变量是操作系统用来存储配置信息的键值对。它们决定了 Shell 去哪找命令(PATH)、用什么语言(LANG)、编辑器是什么(EDITOR)。

📋 前置知识:需要先掌握以下内容

1. 你将学到


2. 一个 "command not found" 的故事

(1) 痛点:明明装了程序却找不到

小明用 pip install --user 安装了 Python 工具 httpie,但输入 http 时提示:

BASH
http example.com
# Command 'http' not found

小明很困惑:"我明明装好了,为什么系统说没找到?"

(2) PATH —— 告诉 Shell 去哪找程序

Bob 解释:"程序已经装好了,但 Shell 不知道去哪找它。PATH 环境变量就是 Shell 的'寻宝地图'。"

BASH
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# ~/.local/bin 不在 PATH 中,所以 Shell 找不到 http
ls ~/.local/bin/http*
# /home/charlie/.local/bin/http

# 将 ~/.local/bin 加入 PATH
export PATH="$PATH:$HOME/.local/bin"
http example.com    # 这次能用了

(3) 收益:理解了一切背后的机制

小明知道了 export PATH="$PATH:~/bin" 放在 .bashrc 中就能永久生效。后来他每次安装新工具,都知道去检查 PATH 是否包含了安装目录。


3. 知识点讲解

(1) 什么是环境变量

环境变量是存储在操作系统中的键值对,所有子进程都会继承它们。

TEXT 📖 仅展示
# 查看所有环境变量
printenv

# 查看单个变量
echo $HOME
echo $USER
echo $SHELL
echo $LANG
echo $PWD

常见环境变量:

变量 含义 典型值
HOME 当前用户的家目录 /home/alice
USER 当前用户名 alice
SHELL 当前 Shell 路径 /bin/bash
PATH 命令搜索路径 /usr/bin:/bin:/usr/local/bin
LANG 语言和编码 zh_CN.UTF-8
PWD 当前工作目录 /home/alice/projects
OLDPWD 上一个工作目录 /etc
EDITOR 默认编辑器 vim

(2) PATH——命令搜索路径

当你输入 ls 时,Shell 会依次在 PATH 列出的每个目录中查找 ls 程序。找到就执行,找不到就报 command not found

💡 提示:PATH 的工作原理就是"按顺序搜索"——Shell 从左到右依次查找 PATH 中的每个目录,找到第一个匹配就停止。因此 PATH 中靠前的目录优先级更高。如果新安装的程序似乎没生效,可能是旧版本在 PATH 中排在前面。

BASH
# 查看当前 PATH
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 查看某个命令在哪个目录
which ls
# /usr/bin/ls

# 查看命令的所有可能位置(包括别名、函数)
type ls
# ls is aliased to `ls --color=auto'

(3) 设置和取消环境变量

BASH
# 临时设置(仅在当前 Shell 生效)
MY_VAR="hello"

# 导出为环境变量(子进程也能访问)
export MY_VAR="hello"

# 一条命令完成设置和导出
export MY_VAR="hello"

# 取消环境变量
unset MY_VAR

# 在一行命令中临时设置(不污染当前环境)
LANG=ja_JP.UTF-8 date

(4) Shell 配置文件加载顺序

理解配置文件加载顺序很重要——知道为什么有时修改 ~/.bashrc 没有效果:

BASH

登录 Shell(SSH 登录、tty 登录):
    /etc/profile
    ~/.bash_profile   (如果存在,跳过下面两个)
    ~/.bash_login
    ~/.profile

非登录 Shell(打开新的终端):
    /etc/bash.bashrc
    ~/.bashrc

ℹ️ 说明.bashrc.profile 的加载时机不同——SSH 登录时加载 .profile,打开新终端窗口时加载 .bashrc。最佳实践是在 .profile 中加 source ~/.bashrc,然后所有配置都写在 .bashrc 中,这样无论哪种方式登录都能生效。

最佳实践:.bash_profile 中添加:

BASH
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi

然后所有自定义配置都写在 .bashrc 中。

▶ 示例:查看和设置环境变量

BASH
# 查看环境变量
echo "我的家目录是: $HOME"
echo "当前用户: $USER"
echo "我的 Shell: $SHELL"

# 设置临时变量
export GREETING="Hello from Linux"
echo $GREETING

# 新开一个终端窗口看看 $GREETING 还在吗?
# 答案:不在——因为临时变量只在当前 Shell 有效

输出:

TEXT 📖 仅展示
我的家目录是: /home/alice
当前用户: alice
我的 Shell: /bin/bash
Hello from Linux

▶ 示例:理解 PATH

BASH
# 查看当前 PATH
echo $PATH | tr ':' '\n'    # 每行显示一个路径

# 查看 ls 命令从哪个目录加载
which ls
# /usr/bin/ls

# 如果 PATH 错了会怎样?
PATH=""      # 清空 PATH(危险!)
ls
# bash: ls: No such file or directory

# 恢复 PATH
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

输出:

TEXT 📖 仅展示
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/bin/ls

▶ 示例:将 ~/scripts 加入 PATH(永久)

BASH
# 创建自己的脚本目录
mkdir -p ~/scripts

# 将 ~/scripts 加入 PATH(写入 .bashrc)
echo 'export PATH="$PATH:$HOME/scripts"' >> ~/.bashrc

> 💡 **提示**:想让环境变量永久生效,必须将 `export` 命令写入 `~/.bashrc`(或 `~/.profile`)。修改后执行 `source ~/.bashrc` 立即生效,否则只在新打开的终端中才会加载新配置。

# 重新加载
source ~/.bashrc

# 验证
echo $PATH | tr ':' '\n' | grep scripts
# /home/alice/scripts

输出:

TEXT 📖 仅展示
/home/alice/scripts

▶ 示例:常用开发环境变量配置

BASH
# 在 ~/.bashrc 中添加以下内容

# 默认编辑器
export EDITOR=vim

# 语言环境
export LANG=zh_CN.UTF-8

# Python 开发
export PYTHONSTARTUP=~/.pythonrc    # Python 交互式启动脚本
export PIP_REQUIRE_VIRTUALENV=true  # pip 要求虚拟环境

# Node.js 开发
export NODE_ENV=development
export npm_config_prefix=~/.npm-global

# Go 开发
export GOPATH=$HOME/go
export PATH="$PATH:$GOPATH/bin"

# 自己的脚本
export PATH="$PATH:$HOME/scripts"
export PATH="$PATH:$HOME/.local/bin"

输出:

TEXT 📖 仅展示
EDITOR=vim
LANG=zh_CN.UTF-8
PYTHONSTARTUP=/home/alice/.pythonrc
PIP_REQUIRE_VIRTUALENV=true
NODE_ENV=development
GOPATH=/home/alice/go

▶ 示例:检查命令是否可以找到

BASH
# 用 which 查看命令路径
which python3
# /usr/bin/python3

# 用 type 查看命令类型(别名/函数/内建/外部命令)
type ls
# ls 是 `ls --color=auto' 的别名
type cd
# cd 是 shell 内建
type node
# node 是 /usr/bin/node

# 用 command -v(最可靠的方式)
command -v python3
# /usr/bin/python3

输出:

TEXT 📖 仅展示
/usr/bin/python3
ls 是 `ls --color=auto' 的别名
cd 是 shell 内建
node 是 /usr/bin/node
/usr/bin/python3

▶ 综合示例:排查 "command not found" 问题

BASH
#!/bin/bash
# debug-path.sh - 排查命令找不到的问题

CMD="${1:-http}"

echo "=== 1. 命令是什么 ==="
type "$CMD" 2>/dev/null || echo "type: 未找到 $CMD"

echo ""
echo "=== 2. 哪些 PATH 目录包含这个命令 ==="|
IFS=':' read -ra PATHS <<< "$PATH"
for dir in "${PATHS[@]}"; do
    if [ -f "$dir/$CMD" ]; then
        echo "找到: $dir/$CMD"
    fi
done

echo ""
echo "=== 3. 用 find 全局搜索 ==="
find /usr /opt $HOME -name "$CMD" -type f 2>/dev/null | head -5

echo ""
echo "=== 4. 如果找到但没在 PATH 中 ==="
echo "执行: export PATH=\"\$PATH:/找到的目录\""

❓ 常见问题

Q: PATH 的顺序重要吗? A: 非常重要!Shell 按顺序搜索 PATH 中的目录,找到第一个匹配就停止。如果 /usr/local/bin 在前,它会优先于 /usr/bin。这就是为什么新安装的程序有时还是运行了旧版本——检查 PATH 顺序。

Q: 环境变量重启后会消失吗? A: 临时用 export 设置的会在重启后消失。要想持久化,必须将 export 命令写入 Shell 配置文件(~/.bashrc~/.bash_profile)。

Q: .bashrc.bash_profile 哪个先执行? A: 登录 Shell:/etc/profile~/.bash_profile~/.bash_login~/.profile(如果前序文件不存在)。非登录 Shell:/etc/bash.bashrc~/.bashrc

Q: 怎么设置全局环境变量(所有用户生效)? A: 写入 /etc/environment(简单键值对,不支持脚本)或 /etc/profile.d/custom.sh(支持 Shell 语法,需要 root 权限)。

Q: printenvset 有什么区别? A: printenv 只显示环境变量(export 的变量)。set 显示所有变量,包括 Shell 局部变量和函数。想看完整的环境用 printenv,想调试脚本用 set


📖 小节


📝 作业

  1. 基础题(难度⭐):查看当前 PATH(用 tr ':' '\n' 分行显示更清晰),并用 which python3type cd 理解命令类型
  2. 进阶题(难度⭐⭐):创建一个 ~/scripts 目录,写一个简单的 hello.sh 脚本,将其加入 PATH 并直接运行;在 .bashrc 中设置 EDITOR=vim(或 nano)并 source 验证
  3. 挑战题(难度⭐⭐⭐):写一个 debug-path.sh 脚本,接收一个命令名参数,自动排查该命令是否在 PATH 中、哪个目录包含它、如果不在 PATH 中则给出修复建议
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏