5.2.5 标准输入输出与重定向(>、>>、<、2>、2>&1)
标准输入输出与重定向(>、>>、<、2>、2>&1)#
标准输入(stdin,FD 0)、标准输出(stdout,FD 1)、标准错误(stderr,FD 2)是 Shell 的默认数据流。重定向用于改变这些数据流的去向,支撑日志记录、批处理与自动化。
原理草图(数据流)
环境准备(安装/确认)
- 大多数 Linux 已预装 Bash,无需额外安装。可用以下命令确认:
which bash
bash --version
- 若是精简系统,使用包管理器安装(示例为 Ubuntu):
sudo apt-get update
sudo apt-get install -y bash
关键命令与解释
- >:覆盖写入标准输出到文件
- >>:追加写入标准输出到文件
- <:从文件读取作为标准输入
- 2>:重定向标准错误
- 2>&1:将标准错误合并到标准输出
完整示例:创建输入文件并演示重定向
# 1) 准备输入文件
cat > /tmp/input.txt <<'EOF'
alpha
beta
gamma
EOF
# 2) 标准输出覆盖写入
wc -l /tmp/input.txt > /tmp/out.log
cat /tmp/out.log
# 预期:显示行数(3)
# 3) 标准输出追加写入
echo "done" >> /tmp/out.log
cat /tmp/out.log
# 预期:原结果后追加一行 done
# 4) 标准输入重定向
wc -l < /tmp/input.txt
# 预期:仅输出行数,不显示文件名
# 5) 标准错误重定向
find /root -name "*.log" 2> /tmp/err.log
cat /tmp/err.log
# 预期:显示权限错误信息
# 6) 合并 stdout 与 stderr
( echo ok; ls /no_such_dir ) > /tmp/all.log 2>&1
cat /tmp/all.log
# 预期:同时包含 ok 和错误信息
重定向顺序差异(重点排错)
# 情况A:先重定向 stdout,再合并 stderr => 两者都进文件
ls /no_such_dir > /tmp/a.log 2>&1
# 情况B:先合并 stderr 到当前 stdout(终端),再重定向 stdout => 错误仍在终端
ls /no_such_dir 2>&1 > /tmp/b.log
- 解释:重定向按从左到右执行;先合并到哪里就会受影响。
典型运维场景(结构化日志)
# 分离正常输出与错误输出
/opt/app/bin/run.sh > /var/log/app/out.log 2> /var/log/app/err.log
# 静默执行(丢弃输出)
/opt/app/bin/run.sh > /dev/null 2>&1
# 追加记录执行日志
/opt/app/bin/run.sh >> /var/log/app/run.log 2>&1
常见排错与定位
- 文件空或无写入:确认顺序是否正确、目录是否可写
bash
ls -ld /var/log/app
id
- 输出仍在终端:检查是否为 cmd 2>&1 > file 的顺序错误
- 覆盖导致历史日志丢失:用 >> 追加替代 >
- 权限错误:使用 sudo 或更换可写目录
练习
1. 生成 5 行文本,统计行数并将结果追加到 /tmp/count.log。
2. 构造一个会报错的命令,将 stdout 与 stderr 分离保存。
3. 通过 < 重定向输入,比较 wc -l file 与 wc -l < file 输出差异并记录原因。