在 Shell 脚本和操作系统中,环境变量(Environment Variables) 是一种动态命名的值,用于存储和传递系统或用户自定义的配置信息。它们在进程执行时被继承,并影响程序的行为。
一、环境变量的基本概念
-
作用
- 存储系统信息:如用户主目录(
HOME
)、命令搜索路径(PATH
)、当前 Shell 类型(SHELL
)等。 - 配置程序行为:程序可以通过环境变量动态调整其行为(如调试模式、日志路径等)。
- 进程间通信:父进程可以将环境变量传递给子进程。
- 存储系统信息:如用户主目录(
-
生命周期
- 临时环境变量:在当前 Shell 会话中有效,关闭终端后失效。
- 永久环境变量:通过配置文件(如
~/.bashrc
、~/.zshrc
)设置,每次启动 Shell 时自动加载。
二、常见环境变量
变量名 | 说明 |
---|---|
PATH | 命令的搜索路径,用冒号 : 分隔目录。 |
HOME | 当前用户的主目录(如 /home/username )。 |
USER | 当前用户名。 |
SHELL | 当前使用的 Shell 路径(如 /bin/bash )。 |
PWD | 当前工作目录的绝对路径。 |
OLDPWD | 上一个工作目录的绝对路径。 |
TERM | 终端类型(如 xterm-256color )。 |
LANG | 语言环境设置(如 en_US.UTF-8 )。 |
EDITOR | 默认文本编辑器(如 vim )。 |
PS1 | 主提示符(如 [user@host ~]$ )。 |
三、环境变量的操作
1. 查看环境变量
- 查看所有环境变量:
env # 显示所有环境变量 printenv # 同上
- 查看单个环境变量:
echo $PATH # 输出 PATH 变量的值
2. 设置环境变量
-
临时设置(仅当前 Shell 会话有效):
export VAR_NAME=value
示例:
export GREETING="Hello, World!" echo $GREETING # 输出 Hello, World!
-
永久设置(需写入配置文件):
- Bash 用户:编辑
~/.bashrc
或~/.bash_profile
。nano ~/.bashrc # 添加以下行 export PATH=$PATH:/your/custom/path
- Zsh 用户:编辑
~/.zshrc
。nano ~/.zshrc # 添加以下行 export PATH=$PATH:/your/custom/path
- 全局设置:编辑
/etc/profile
或/etc/environment
(需管理员权限)。
- Bash 用户:编辑
-
使配置生效:
source ~/.bashrc # 或 source ~/.zshrc
3. 删除环境变量
unset VAR_NAME
示例:
unset GREETING
echo $GREETING # 输出空
4. 只读环境变量
readonly VAR_NAME
示例:
export PI=3.14
readonly PI
PI=3.1415 # 错误:只读变量不能修改
四、环境变量的作用域
-
Shell 内部变量
- 仅在当前 Shell 中有效,未通过
export
导出的变量不会传递给子进程。
VAR="local" echo $VAR # 输出 local bash -c 'echo $VAR' # 输出空(子进程未继承)
- 仅在当前 Shell 中有效,未通过
-
环境变量
- 通过
export
导出后,会传递给子进程。
export VAR="global" echo $VAR # 输出 global bash -c 'echo $VAR' # 输出 global
- 通过
五、PATH 变量详解
PATH
是最重要的环境变量之一,决定了 Shell 如何查找命令。
1. 查看 PATH
echo $PATH
# 输出示例:/usr/local/bin:/usr/bin:/bin
2. 修改 PATH
- 临时添加路径:
export PATH=$PATH:/your/custom/path
- 永久添加路径:
将上述命令写入~/.bashrc
或~/.zshrc
,然后执行source
。
3. 示例:添加自定义脚本路径
假设用户有一个自定义脚本 ~/scripts/hello.sh
,希望全局可用:
# 编辑配置文件
echo 'export PATH=$PATH:~/scripts' >> ~/.bashrc
source ~/.bashrc
# 验证
hello.sh # 应直接执行脚本
六、环境变量的使用技巧
-
变量替换与字符串操作
- 默认值:
echo ${EDITOR:-nano} # 如果 EDITOR 未定义,使用 "nano"
- 截取字符串:
path="/home/user/docs" echo ${path##*/} # 输出 "docs"(从左删除最长匹配) echo ${path%/*} # 输出 "/home/user"(从右删除最短匹配)
- 默认值:
-
调试环境变量
- 启用调试模式:
set -x # 显示执行的命令和变量值
- 禁用调试模式:
set +x
- 启用调试模式:
-
环境变量继承
- 子进程会继承父进程的环境变量,但修改子进程的变量不会影响父进程。
export VAR="parent" bash -c 'VAR="child"; echo $VAR' # 输出 "child" echo $VAR # 输出 "parent"
七、常见问题与解决方案
-
命令找不到(Command Not Found)
- 原因:目标命令的路径未加入
PATH
。 - 解决:检查
PATH
并添加相应目录。export PATH=$PATH:/usr/local/bin
- 原因:目标命令的路径未加入
-
环境变量未生效
- 原因:未正确导出或未重新加载配置文件。
- 解决:
export VAR_NAME=value source ~/.bashrc # 或重新启动终端
-
环境变量冲突
- 原因:多个配置文件(如
.bashrc
和.bash_profile
)定义了相同的变量。 - 解决:检查并统一配置文件中的变量定义。
- 原因:多个配置文件(如
-
只读变量修改失败
- 原因:尝试修改只读变量。
- 解决:先
unset
再重新定义(需谨慎)。unset PI export PI=3.1415
八、环境变量的持久化配置
Shell 类型 | 配置文件 | 说明 |
---|---|---|
Bash | ~/.bashrc | 用户级,交互式非登录 Shell |
Bash | ~/.bash_profile | 用户级,登录 Shell |
Zsh | ~/.zshrc | 用户级,交互式 Shell |
全局 | /etc/profile | 系统级,所有用户共用 |
全局 | /etc/environment | 系统级,格式为 VAR=value |
示例:在 .bashrc
中添加环境变量
# 打开配置文件
nano ~/.bashrc
# 添加以下行
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$JAVA_HOME/bin:$PATH
# 保存并退出,然后执行
source ~/.bashrc
九、高级用法
-
条件设置环境变量
if [ "$OSTYPE" = "darwin"* ]; then export PATH="/usr/local/bin:$PATH" fi
-
动态环境变量
export TIMESTAMP=$(date +%Y%m%d) echo "Backup file: backup_$TIMESTAMP.tar.gz"
-
嵌套变量
export BASE_DIR=/home/user export LOG_DIR=$BASE_DIR/logs echo $LOG_DIR # 输出 /home/user/logs