第 33 课 - 环境变量与 export
1. 学习目标
完成本课后,你将能够:
- 理解什么是环境变量,以及它在进程间通信中的作用。
- 掌握使用
export命令将一个 Shell 变量提升为环境变量。 - 区分局部变量(Shell 变量)和环境变量在作用域上的根本区别。
- 了解系统启动文件(如
~/.bashrc,~/.profile)如何持久化环境变量设置。 - 熟练运用相关命令查看、设置和取消环境变量。
2. 核心概念
什么是环境变量?
在之前的课程中,我们学习了在 Shell 中定义变量。但是,有些变量我们不仅希望在当前 Shell 会话中使用,还希望它能被当前 Shell 启动的任何子程序(子进程) 所知晓和使用。这种能被子进程继承的变量,就叫做环境变量。
你可以把局部变量想象成你写在个人笔记本上的笔记,只有你自己知道。 而环境变量则像是写在你工位公告板上的公告,任何进入你工位(启动子进程)的人都能看到。
export 的作用
export 命令就是那个将你的“个人笔记”张贴到“公共公告板”的动作。它将指定的变量标记为环境变量,从而使其对子进程可见。
关键点:export 不会创建新变量,它只是改变一个已有变量的属性。所以,正确的做法通常是:先赋值,再导出。
作用域对比
| 特性 | 局部变量 (Shell 变量) | 环境变量 (通过 export) |
|---|---|---|
| 定义方式 | VAR_NAME=value | 先定义,再 export VAR_NAME 或直接 export VAR_NAME=value |
| 作用域 | 仅在当前 Shell 会话中有效。 | 当前 Shell 及其所有子进程(孙进程等)均有效。 |
| 子进程是否可见 | 否 | 是 |
| 典型用途 | 脚本中的临时计算、循环计数器。 | 配置程序运行的环境,如 PATH, HOME, LANG。 |
系统启动文件与持久化
你设置的变量(无论是局部还是环境)在终端关闭后都会丢失。为了让环境变量在每次打开终端或登录系统时自动生效,你需要将 export 命令写入特定的配置文件中。常见的文件有:
~/.bashrc:每次启动一个交互式非登录 Shell(如打开一个新的终端窗口)时执行。~/.profile或~/.bash_profile:每次登录时执行(适用于登录 Shell)。 将export命令写入这些文件,就能实现环境变量的“持久化”。
3. 代码示例
示例一:验证环境变量的继承
#!/bin/bash
# 1. 定义一个局部变量
MY_LOCAL_VAR="I am local"
echo "在父Shell中:MY_LOCAL_VAR=$MY_LOCAL_VAR"
# 2. 启动一个子进程(另一个bash实例)来测试继承
# 子进程中尝试打印父进程的变量
bash -c 'echo "在子进程中:MY_LOCAL_VAR=$MY_LOCAL_VAR"'
# 输出:在子进程中:MY_LOCAL_VAR= (空的,因为子进程看不到)
echo "---"
# 3. 定义并导出一个环境变量
export MY_ENV_VAR="I am exported"
echo "在父Shell中:MY_ENV_VAR=$MY_ENV_VAR"
# 4. 再次启动子进程测试
bash -c 'echo "在子进程中:MY_ENV_VAR=$MY_ENV_VAR"'
# 输出:在子进程中:MY_ENV_VAR=I am exported (成功继承!)
示例二:管理环境变量的常用命令
#!/bin/bash
# 1. 导出一个变量(两种等价方式)
export EDITOR=vim
PAGER=less && export PAGER
# 2. 查看当前 Shell 的所有环境变量
echo "=== 使用 env 命令 ==="
env | head -n 5 # 只看前5行
echo ""
echo "=== 使用 printenv 命令查看特定变量 ==="
printenv HOME
# 3. 取消一个变量的导出属性(它变回局部变量,但值还在)
export MY_VAR="hello"
echo "导出前,子进程看到:"
bash -c 'echo MY_VAR=$MY_VAR' # 输出 hello
# 取消导出
declare +x MY_VAR # 或者使用 `export -n MY_VAR`
echo "取消导出后,子进程看到:"
bash -c 'echo MY_VAR=$MY_VAR' # 输出空
# 4. 完全删除一个变量
unset MY_VAR
echo "变量MY_VAR已删除:$MY_VAR"
示例三:在Bash脚本中利用环境变量
#!/bin/bash
# 脚本名:check_env.sh
# 功能:演示环境变量如何被脚本(子进程)使用
echo "欢迎来到脚本!"
echo "你的用户名是:$(whoami)"
echo "你的家目录是:$HOME"
echo "你的默认编辑器是:$EDITOR"
echo "脚本自己的变量 SCRIPT_VAR 不存在于父Shell中"
你需要在调用它之前设置好环境变量:
$ export EDITOR=nano
$ ./check_env.sh
4. 实践练习
练习一:基础操作
- 定义一个局部变量
MY_NAME,值为你的名字。 - 尝试在一个新的
bash -c子进程中打印它,观察结果。 - 使用
export将其导出为环境变量。 - 再次在子进程中验证它是否可见。
- 最后,使用
unset删除该变量。
预期输出:
# 第2步输出应为空
# 第4步输出应为你的名字
练习二:启动文件配置
- 编辑你的
~/.bashrc文件(使用nano ~/.bashrc或vim ~/.bashrc)。 - 在文件末尾添加一行:
export MY_COURSE="Linux System Administration" - 保存并退出。
- 请新开一个终端窗口(或执行
source ~/.bashrc)。 - 在新终端中,输入
echo $MY_COURSE验证是否生效。
练习三:综合应用
编写一个简单的脚本 greet.sh,要求:
- 脚本首先检查是否存在名为
USER_ROLE的环境变量。 - 如果存在且值为
admin,则输出“欢迎回来,管理员!”。 - 如果存在且值为
guest,则输出“你好,访客!”。 - 如果不存在,则输出
“未知角色,请设置 USER_ROLE 环境变量。” - 通过在命令行设置不同的
USER_ROLE环境变量并运行脚本进行测试。
预期输出:
$ ./greet.sh
未知角色,请设置 USER_ROLE 环境变量。
$ USER_ROLE=admin ./greet.sh
欢迎回来,管理员!
$ export USER_ROLE=guest
$ ./greet.sh
你好,访客!
5. 常见错误
- 忘记
export:这是最典型的错误。定义了变量,但在子脚本或程序中死活读不到。记得先定义,再导出。 - 过度使用全局变量:环境变量是全局的,容易造成命名冲突和不可预见的依赖。仅在确需跨进程通信时使用(如配置程序路径、语言、终端类型等)。
- 修改启动文件后不生效:修改了
~/.bashrc等文件后,需要重启终端或运行source ~/.bashrc才能让更改在当前会话生效。 - 变量名拼写错误:Shell 对大小写敏感。
Path和PATH是两个完全不同的变量。 - 在脚本中
export却希望影响调用它的父 Shell:export只能向下(向子进程)传递信息,不能向上(向父进程)传递。在子脚本中设置的export变量,在脚本执行结束后就消失了。
6. 小结
- 环境变量是能够被子进程继承的特殊变量,用于传递环境配置信息。
export命令将局部变量提升为环境变量,是使其对子进程可见的关键操作。- 环境变量的作用域是当前 Shell 及其派生的所有子进程。
- 要持久化环境变量,需要将
export命令写入 Shell 启动文件(如~/.bashrc)。 - 常用管理命令:
export(设置/导出)、env或printenv(查看)、unset(删除变量)。 - 谨慎使用环境变量,避免污染全局命名空间。
练习编辑器
rust
Loading...