1.8.7 管道与重定向实战(|、>、>>、2>、xargs)

在日常运维中,管道与重定向用于将多个命令串联成处理链,或将输出/错误输出写入文件与日志。掌握 |>>>2>xargs 能显著提升批量处理与排错效率。

核心概念与规则#

  • 标准输出(stdout):默认输出到终端,文件描述符为 1
  • 标准错误(stderr):错误输出到终端,文件描述符为 2
  • 管道 |:将前一个命令的标准输出作为后一个命令的标准输入
  • 重定向 > >>:将标准输出覆盖/追加到文件
  • 错误重定向 2>:将标准错误输出重定向到文件
  • 组合重定向>file 2>&1&> 将 stdout 与 stderr 合并

原理草图(数据流)#

文章图片

常见用法与实战#

1)管道基础串联#

  • 统计系统中活跃的 SSH 连接数:
ss -tn | grep ':22' | wc -l

解释:ss -tn 输出 TCP 连接;grep ':22' 过滤 22 端口;wc -l 统计行数。

  • 查看 nginx 访问日志中 404 的前 5 个 IP:
grep ' 404 ' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -5

解释:提取 IP、计数、降序排序、取前 5。

2)输出重定向与日志记录#

  • 将命令输出覆盖写入文件:
ps aux > /tmp/ps.txt

预期效果:/tmp/ps.txt 内容被覆盖为当前进程列表。

  • 将命令输出追加写入文件:
df -h >> /tmp/disk.log

预期效果:/tmp/disk.log 末尾新增磁盘使用信息。

  • 仅记录错误输出:
find / -name "*.conf" 2> /tmp/find_err.log

预期效果:无权限等错误写入 /tmp/find_err.log

  • 标准输出与错误输出分开保存:
grep 'error' /var/log/syslog > /tmp/error.log 2> /tmp/grep_err.log
  • 合并 stdout 与 stderr 到同一文件:
systemctl status nginx > /tmp/nginx_status.log 2>&1

3)xargs 批量处理#

xargs 可把标准输入转换为命令参数,适合批量操作。

  • 批量删除 tmp 目录下超过 7 天的文件:
find /tmp -type f -mtime +7 | xargs rm -f

解释:find 输出文件列表,xargs 变为 rm -f file1 file2...

  • 批量查看多个文件末尾 50 行:
ls /var/log/*.log | xargs -n 1 tail -n 50

解释:-n 1 每次只传一个文件,避免参数过长。

  • 防止文件名包含空格的问题(推荐):
find /data -type f -print0 | xargs -0 rm -f

解释:-print0/-0 以 NULL 分隔,安全处理空格。

  • 控制一次传递的参数数量:
cat file.list | xargs -n 5 echo

预期效果:每行最多 5 个参数输出。

组合实战:日志采样与归档#

目标:采样 1 分钟内的错误日志、归档到目录并记录执行日志。

# 1) 过滤错误日志并追加到采样文件
grep 'ERROR' /var/log/app/app.log >> /tmp/app_error_sample.log

# 2) 打包采样文件,并将输出与错误写到统一日志
tar -czf /tmp/app_error_sample.tar.gz /tmp/app_error_sample.log > /tmp/archive.log 2>&1

# 3) 显示归档结果
ls -lh /tmp/app_error_sample.tar.gz

典型排错场景#

  • 服务启动失败排错并留存日志
systemctl start nginx > /tmp/nginx_start.log 2>&1

说明:启动失败的错误输出会写入日志,便于回溯。

  • 定位被删除但仍占用磁盘的文件
lsof | grep deleted | awk '{print $2, $7, $9}' | sort -u > /tmp/deleted_files.log

说明:进程 PID、文件大小、路径被记录下来。

  • 查看大文件占用并排序
du -ah /var | sort -rh | head -20 > /tmp/top20_size.log

常见问题与排错#

  • 管道无输出:确认前一条命令是否输出到 stdout;必要时加 2>&1 合并错误输出。
  • xargs 提示参数过长:加入 -n 限制参数数量,或改用 -0 模式。
  • 重定向覆盖误写:用 >> 或先备份:
cp /tmp/ps.txt /tmp/ps.txt.bak && ps aux > /tmp/ps.txt

练习题#

  1. 统计 /var/log/nginx/access.log 中访问次数最多的 10 个 URL。
  2. /etc 目录下所有 .conf 文件列表写入 /tmp/conf.list,错误写入 /tmp/conf.err
  3. 生成 /tmp/test.list(含 20 行随机数),用 xargs 每 4 个一组输出。
  4. 找出 /var 下最大的 15 个文件并保存到 /tmp/var_top15.txt
  5. 处理带空格文件名的删除场景,给出一条安全命令。