「Linux文件及目录管理」输入输出重定向与管道

99 阅读4分钟

知识点解析

输入/输出重定向

  • 标准输入(stdin):默认从键盘读取,文件描述符为0
  • 标准输出(stdout):默认输出到终端,文件描述符为1
  • 标准错误(stderr):默认输出到终端,文件描述符为2
  • 重定向符号
    • >:覆盖输出到文件(如command > file)。
    • >>:追加输出到文件(如command >> file)。
    • <:从文件读取输入(如command < file)。
    • 2>:重定向错误输出(如command 2> error.log)。
    • &>:重定向所有输出(标准输出+错误输出)到文件(如command &> all.log)。

管道(|

  • 将前一个命令的输出作为后一个命令的输入。
  • 示例:command1 | command2

案例代码与解析

案例:重定向标准输出到文件

  • 将ls命令的输出保存到文件(test.txt)
  • 将当前时间追加到文件(test.txt)
# 将ls命令的输出保存到目录列表文件
ls -l > test.txt
# 查看test.txt写入的内容
cat test.txt
# 总用量 4
# -rw-------. 1 root root 1228 8月  26 2021 anaconda-ks.cfg
# -rw-r--r--  1 root root    0 6月  21 17:17 test.txt
# 将当前时间追加到日志文件
date >> test.txt
cat test.txt
# 总用量 4
# -rw-------. 1 root root 1228 8月  26 2021 anaconda-ks.cfg
# -rw-r--r--  1 root root    0 6月  21 17:17 test.txt
# 2025年 06月 21日 星期六 17:18:14 CST

解析

  • ls -l的输出被覆盖写入test.txt(若文件不存在则创建)。
  • date的输出被追加到test.txt末尾。
  • >会清空目标文件后写入,>>会保留原有内容并在末尾追加。

案例:重定向标准错误

# 查看当前目录下的内容
ls
# anaconda-ks.cfg
# 查找不存在的文件,将错误信息保存到error.log(终端不显示错误)
find /nonexistent 2> error.log
# 查看当前目录下的内容
ls
# anaconda-ks.cfg  error.log
# 查看error.log的内容
cat error.log
# find: ‘/nonexistent’: 没有那个文件或目录

# 合并标准输出和错误输出到同一文件
cat nonexistent_file.txt &> full_log.txt
cat full_log.txt
# cat: nonexistent_file.txt: 没有那个文件或目录

解析

  • find命令的错误输出被保存到error.log,终端不显示错误。
  • cat命令的标准输出和错误输出均被保存到full_log.txt
  • 2>仅重定向错误输出,&>> file 2>&1会重定向所有输出。

案例:管道操作

# 统计当前目录下文件的数量
ls -l | grep "^-" | wc -l
# 1

# 筛选出/etc目录下以.conf结尾的文件并显示行号
grep -n ".conf$" /etc/* 2>/dev/null | less

解析

  • ls -l列出目录内容。
  • grep "^-"筛选出普通文件(以-开头的行)。
  • wc -l统计行数(即文件数量)。
  • grep -n显示匹配行的行号,2>/dev/null丢弃错误信息。

案例:混合使用重定向与管道

# 将错误输出重定向到/dev/null(丢弃),仅统计标准输出
ls -l /etc /nonexistent 2>/dev/null | grep "^-" | wc -l
# 87

# 统计/var/log目录下.log文件的数量(忽略错误)
ls /var/log/*.log 2>/dev/null | wc -l
# 2

解析2>/dev/null丢弃错误输出,仅处理标准输出(如/etc目录下的文件)。

案例:从文件读取输入

# 使用文件内容作为grep的输入(例如搜索users.txt中的用户名)
grep "root" < /etc/passwd
# root:x:0:0:root:/root:/bin/bash
# operator:x:11:0:operator:/root:/sbin/nologin

# 等价写法(更直观)
grep "root" /etc/passwd

解析<从文件读取输入,但直接传递文件名(如grep "root" /etc/passwd)更常用。

常见错误与解决方法

错误command > file覆盖了重要文件。
解决方法:使用>>追加或先备份文件。

cp file file.bak  # 备份
command > file    # 安全覆盖

错误:管道中命令顺序错误导致结果不符合预期。
解决方法:逐步测试每个命令的输出。

ls -l          # 查看原始输出
ls -l | grep "^-"  # 测试管道中间结果

错误:重定向符号写错(如>写成1>)。
解决方法:明确文件描述符(1>可省略,2>必须显式指定)。

command > file      # 等价于 command 1> file
command 2> error.log # 必须显式写2>

错误:忘记合并错误输出导致日志不完整。
解决方法:使用&>> file 2>&1

command &> all.log  # 合并所有输出
command > output.log 2>&1  # 等价写法

理论练习

题目:如何将echo "Hello"的输出保存到greeting.txt,同时将错误信息保存到error.log
答案

echo "Hello" > greeting.txt 2> error.log
# 或
echo "Hello" &> greeting.txt 2> error.log # 会覆盖greeting.txt的错误信息

更优解

echo "Hello" > greeting.txt 2> error.log  # 分别重定向标准输出和错误输出

题目:如何统计/var/log目录下以.log结尾的文件数量?
答案

ls /var/log/*.log 2>/dev/null | wc -l

实操练习

任务:将/etc/passwd文件内容保存到users.txt,并统计行数。
答案

cat /etc/passwd > users.txt
wc -l users.txt

任务:查找当前目录下所有.txt文件,并将文件名保存到text_files.txt
答案

find . -name "*.txt" > text_files.txt

任务:将ps aux的输出过滤出包含nginx的进程,并保存到nginx_processes.txt
答案

ps aux | grep "nginx" > nginx_processes.txt

任务:统计当前目录下所有.sh脚本文件的数量(忽略错误)。
答案

ls *.sh 2>/dev/null | wc -l

任务:将tar -czf archive.tar.gz /large_dir的输出和错误信息合并保存到tar_log.txt
答案

tar -czf archive.tar.gz /large_dir &> tar_log.txt

知识总结

  1. 重定向>覆盖,>>追加,<输入,2>错误输出,&>所有输出。
  2. 管道|连接命令,前一个命令的输出作为后一个命令的输入。
  3. 典型场景:日志记录、数据筛选、多命令协作。