Linux 重定向、管道与环境变量
系统梳理 Linux 目录结构、标准输入输出、重定向、命令行管道,以及环境变量和 PATH 的工作方式。
内容概览
这份课件围绕 Linux 命令行中的三条主线展开:
- FHS 如何规范 Linux 目录结构;
- 命令如何通过标准输入、标准输出、标准错误与文件或其他命令交换数据;
- 系统如何借助环境变量,特别是
PATH,查找并运行程序。
一、FHS:Linux 目录结构规范
FHS(Filesystem Hierarchy Standard,文件系统层次结构标准)约定了 Linux 中常见目录的用途,使软件安装位置和系统文件组织方式保持一致。
| 目录 | 主要用途 |
|---|---|
/bin |
基础用户命令;现代发行版常链接到 /usr/bin |
/sbin |
系统管理命令;现代发行版常链接到 /usr/sbin |
/boot |
内核、引导器配置等启动文件 |
/dev |
设备文件 |
/etc |
系统级配置文件 |
/home |
普通用户的主目录 |
/root |
root 用户的主目录 |
/lib、/lib64 |
基础共享库和内核模块;可能链接到 /usr/lib* |
/media |
U 盘、光盘等可移动介质的挂载点 |
/mnt |
临时挂载点 |
/opt |
第三方附加软件 |
/proc |
反映进程和内核运行状态的虚拟文件系统,不占用普通磁盘空间 |
/run |
本次启动以来的运行时状态数据 |
/srv |
系统所提供服务的数据 |
/sys |
设备、驱动和内核对象信息的虚拟文件系统 |
/tmp |
临时文件 |
/usr |
用户空间中的程序、库、共享资源等 |
/var |
日志、缓存、队列等经常变化的数据 |
!TIP
不同发行版的具体布局可能略有差异。学习时应记住目录的职责,而不是死记某台机器的全部路径。
二、标准输入、输出与错误
Linux 进程通常会自动打开三个标准数据流:
| 文件描述符 | 名称 | 默认连接 |
|---|---|---|
0 |
stdin,标准输入 | 键盘/终端输入 |
1 |
stdout,标准输出 | 终端显示 |
2 |
stderr,标准错误 | 终端显示 |
stdout 和 stderr 默认都显示在终端上,因此看起来混在一起,但它们是两个独立的数据流,可以分别重定向。
三、输入与输出重定向
1. 输出重定向
bash
whoami > user.txt
>:把标准输出写入文件;文件不存在时创建,存在时先清空再写入。- 连续多次使用
>不会累积内容,只会保留最后一次写入结果。
bash
echo "hello" >> log.txt
>>:追加到文件末尾;文件不存在时同样会创建。
2. 输入重定向
bash
cat < input.txt
<:让命令从指定文件读取标准输入。cat input.txt是把文件名作为参数交给cat;cat < input.txt则是 Shell 先打开文件,再把它接到cat的 stdin。显示结果相同,但数据进入程序的方式不同。
也可以直接执行 cat > input.txt,随后从键盘输入内容,按 Ctrl+D 表示输入结束。
3. 分离标准输出与标准错误
bash
find /home -name test.c > result.txt 2> error.txt
> result.txt等价于1> result.txt,只保存标准输出。2> error.txt单独保存标准错误。
把两者都写入同一个文件:
bash
find /home -name test.c > all.txt 2>&1
这里的 2>&1 表示"让文件描述符 2 指向文件描述符 1 当前指向的位置"。顺序很重要:
bash
command > all.txt 2>&1 # stdout 和 stderr 都进入 all.txt
command 2>&1 > all.txt # stderr 仍指向原终端,只有 stdout 进入 all.txt
在 Bash 中也常见简写:
bash
command &> all.txt
command &>> all.txt
4. 丢弃不需要的信息
/dev/null 是一个特殊设备:写入其中的数据会被直接丢弃,读取时立即得到文件结束。
bash
find /home -name test.c 2> /dev/null
此命令隐藏错误信息,只保留正常结果。
四、命令行管道
管道符 | 把左侧命令的标准输出连接到右侧命令的标准输入,从而把多个简单命令组合成一条数据处理流水线。
text
命令 1 stdout -> stdin 命令 2 stdout -> stdin 命令 3
课件中的典型示例:
bash
last | head -5
last | grep 'whb'
last | grep 'whb' | awk '{print $1,$4,$5,$6,$7}'
last:输出登录历史;head -5:只取前 5 行;grep 'whb':筛选包含指定文本的行;awk:按字段提取和格式化数据。
关键理解:管道默认传递的是 stdout,不会自动传递 stderr。如需把错误也送入管道,可先合并数据流:
bash
command 2>&1 | next_command
五、环境变量与 PATH
1. 查看环境变量
bash
env # 查看当前进程环境中的变量
echo "$PATH" # 查看 PATH
常见环境变量包括:
PATH:可执行程序的搜索路径;HOME:当前用户的主目录;PWD:当前工作目录;SHELL:当前用户的默认 Shell;USER:当前用户名;LANG:语言和字符编码设置。
2. PATH 如何工作
PATH 是一组用冒号 : 分隔的目录。输入不带路径的命令时,Shell 会按从左到右的顺序搜索这些目录,并执行第一个匹配的可执行文件。
bash
echo "$PATH"
command -v ls
command -v 可查看 Shell 最终会怎样解析某条命令;它还能识别别名和内建命令,通常比单纯使用 which 更可靠。
当前目录通常不在 PATH 中,所以运行当前目录下的程序需要显式写出路径:
bash
gcc -o mycmd test.c
./mycmd
其中 . 表示当前目录,./mycmd 表示"执行当前目录下的 mycmd"。默认不搜索当前目录有助于避免误执行同名恶意程序。
3. 临时添加搜索路径
bash
export PATH="$PATH:$HOME/bin"
export使变量可被当前 Shell 启动的子进程继承;- 这种修改只对当前 Shell 会话及其子进程有效;
- 想长期生效,应把设置写入对应 Shell 的启动文件,例如 Bash 的
~/.bashrc,然后重新加载或开启新终端。
!WARNING
课件演示了把个人程序复制到
/usr/bin。实际使用中不建议污染系统包管理目录。个人程序优先放在~/.local/bin或~/bin,本机管理员安装的软件可放在/usr/local/bin,再按需加入PATH。
六、易错点速查
| 需求 | 写法 |
|---|---|
| 覆盖保存标准输出 | command > file |
| 追加保存标准输出 | command >> file |
| 从文件读取标准输入 | command < file |
| 只保存错误 | command 2> error.log |
| 正常输出和错误分别保存 | command > out.log 2> error.log |
| 正常输出和错误合并保存 | command > all.log 2>&1 |
| 丢弃错误 | command 2> /dev/null |
| 将输出交给下一条命令 | `command1 |
| 查看命令解析结果 | command -v name |
| 临时添加 PATH | export PATH="$PATH:/new/path" |
七、核心结论
- Linux 将设备、数据流等抽象为文件,Shell 通过文件描述符连接命令、文件和终端。
- 重定向改变单个命令的数据来源或去向;管道把多个命令的数据流串联起来。
- stdout 与 stderr 是独立通道;理解
0、1、2是掌握复杂重定向的基础。 PATH决定不带路径的命令去哪里查找;搜索顺序会影响实际执行的程序。- 与其写复杂的一体化命令,不如让多个职责单一的命令通过管道协作,这体现了 Unix 工具组合思想。