在前几篇中,我们学习了函数、流程控制等 Shell 编程的基础内容。现在我们来探索更高级的功能:如何控制数据流向、将命令链接在一起、让命令间通信变得可能。
一、输入输出重定向(>、>>、<)
Shell 中的命令执行通常涉及三种“标准设备”:
名称 | 编号 | 说明 |
标准输入(stdin) | 0 | 默认来自键盘 |
标准输出(stdout) | 1 | 默认输出到屏幕 |
标准错误(stderr) | 2 | 默认输出到屏幕(错误信息) |
我们可以使用重定向符将这些流导向不同的位置。
1. 输出重定向
>:输出(覆盖原内容)
echo "Hello" > output.txt效果:将 "Hello" 写入 output.txt(若存在则覆盖)
>>:输出(追加)
echo "Another line" >> output.txt效果:在 output.txt 末尾添加新内容
2. 错误输出重定向
将错误输出到文件:
ls not_exist.txt 2> error.log说明:
- 2> 表示重定向错误输出(stderr)
同时重定向标准输出和错误输出:
command > all.log 2>&1或使用更简洁写法(Bash 4+):
command &> all.log3. 输入重定向
sort < unsorted.txt表示将 unsorted.txt 的内容传给 sort 命令,而不是手动输入。
二、管道(|)
管道是 Shell 最强大的功能之一,它允许一个命令的输出作为另一个命令的输入。
基本语法:
command1 | command2示例 1:过滤搜索内容
ps aux | grep nginx含义:查看所有进程,并只保留包含 "nginx" 的行。
示例 2:统计文件行数
cat mylog.txt | wc -l等价于:
wc -l < mylog.txt示例 3:组合多命令处理
ls -l | grep "^d" | wc -l含义:统计当前目录下的文件夹数量。
三、命令替换(` 或 $())
命令替换可以将命令的输出结果赋值给变量或用于表达式中。
方法 1:使用反引号(老式,不推荐)
now=`date`方法 2:使用 $()(推荐)
now=$(date)
echo "当前时间:$now"示例:获取主机名并输出欢迎语
host=$(hostname)
echo "欢迎登录主机:$host"示例:计算两个目录大小差值
size1=$(du -s /home/user1 | cut -f1)
size2=$(du -s /home/user2 | cut -f1)
echo "差值大小:$((size1 - size2)) KB"四、综合实例:重定向 + 管道 + 替换
#!/bin/bash
log_file="output.log"
# 写入时间戳
echo "运行时间:$(date)" > $log_file
# 统计当前用户进程数量
echo "进程总数:$(ps -u $USER | wc -l)" >> $log_file
# 过滤 nginx 日志中的错误关键词
grep "ERROR" /var/log/nginx/error.log | tee -a $log_filetee 命令:同时输出到屏幕并追加到文件
五、练习题
推荐练习如下:
- 使用重定向将 ls 结果保存到文件中
- 用 ps 和 grep 查看某个程序是否在运行
- 使用命令替换将当前日期写入一个文件名中
- 将某日志文件中包含 404 的行筛选出来并统计数量
六、小结
功能 | 符号 | 用途 |
输出重定向 | > >> | 写入/追加到文件 |
错误重定向 | 2> | 将错误输出到文件 |
管道 | | | |
输入重定向 | < | 从文件中读取输入 |
命令替换 | $(...) | 捕获命令输出作为值 |
掌握这些技巧后,你已经具备写出功能丰富的 Shell 工具的能力!
下一篇预告:
Linux Shell 入门教程(七):文本处理神器 grep、sed、awk 入门
下一节我们将介绍 Shell 中三大神器:grep、sed、awk,它们是处理日志、数据抽取、格式替换等任务不可或缺的利器。