Linux 重定向、管道与环境变量

Linux 重定向、管道与环境变量

系统梳理 Linux 目录结构、标准输入输出、重定向、命令行管道,以及环境变量和 PATH 的工作方式。

内容概览

这份课件围绕 Linux 命令行中的三条主线展开:

  1. FHS 如何规范 Linux 目录结构;
  2. 命令如何通过标准输入、标准输出、标准错误与文件或其他命令交换数据;
  3. 系统如何借助环境变量,特别是 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 是把文件名作为参数交给 catcat < 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 是独立通道;理解 012 是掌握复杂重定向的基础。
  • PATH 决定不带路径的命令去哪里查找;搜索顺序会影响实际执行的程序。
  • 与其写复杂的一体化命令,不如让多个职责单一的命令通过管道协作,这体现了 Unix 工具组合思想。
相关推荐
treacle田1 小时前
达梦数据库-Linux DM数据守护主备集群缩改为单机-记录总结
linux·服务器·数据库·主备集群改单机
YOU OU1 小时前
Spring Cloud概述
后端·spring·spring cloud
IT大白鼠2 小时前
CentOS 7.9 自建 Yum 源服务器搭建指南
linux·服务器·centos
学长毕业设计2 小时前
基于SpringBoot的咖啡馆管理系统的设计与实现(源码+文档+讲解视频)
java·spring boot·后端
骇客野人2 小时前
SpringBoot业财一体化系统设计和落地实施方案
java·spring boot·后端
学长毕业设计2 小时前
基于SpringBoot的教学资源推荐系统的设计与实现(源码+文档+讲解视频)
java·spring boot·后端
名字还没想好☜2 小时前
Java Cleaner 实战:替代废弃的 finalize() 做堆外资源清理,以及强引用导致永不回收的坑
java·后端·spring
高亦真2 小时前
今天是学习嵌入式的第34天
linux·学习·算法
cuijiecheng20182 小时前
从 GinormoTime 到 Rocky Linux:25fps LTC 完整搭建与验证实战
linux·运维·服务器