知识点解析
输入/输出重定向
- 标准输入(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
知识总结
- 重定向:
>覆盖,>>追加,<输入,2>错误输出,&>所有输出。 - 管道:
|连接命令,前一个命令的输出作为后一个命令的输入。 - 典型场景:日志记录、数据筛选、多命令协作。