02 管道通信与 Linux 指令执行 - 凡事有个先后
Linux 管道通信
- Linux 管道通信允许将一个命令的输出作为另一个命令的输入;
- 使用竖线符号
|进行命令连接; - 例:
head -n5 /tmp/kernel.log | tail -n2,先执行head -n5 /tmp/kernel.log,并将其输出结果执行tail -n2,即取/tmp/kernel.log的第 4、5 两行内容。
管道命令符
- 管道命令符
|是一个非常强大的功能,它允许用户将一个命令的输出作为另一个命令的输入。 - 这种机制可以让你将多个命令串联起来,创建复杂的数据处理和任务自动化,而不需要创建中间的临时文件。这种方式可以显著提高命令行工作的效率和灵活性。
- 管道符号:
|,用于连接两个命令。 - 输入和输出:管道将前一个命令的标准输出(stdout)连接到下一个命令的标准输入(stdin)。
基本语法·
bash
command1 | command2这里的 command1 的输出不会显示在屏幕上,而是被 command2 作为输入进行处理。
bash
ls -l | grep "txt"这里,ls -l 列出当前目录下的所有文件和目录的详细信息,grep "txt" 会过滤并显示包含 "txt" 的行。
bash
# 查找一个包含数千个文件的目录中所有 JPEG 图片文件的数量
# 使用 find 命令来搜索文件,然后用 grep 命令来过滤出 .jpg 结尾的文件,最后使用 wc -l 命令来计数
find /path/to/directory -type f | grep "\.jpg$" | wc -lfind /path/to/directory -type f—— 查找指定目录中的所有文件。grep "\.jpg$"—— 从find命令的输出中筛选出以.jpg结尾的文件名。wc -l—— 计算通过管道传递来的行数,即.jpg文件的数量。
工作原理
- 标准输出和标准输入:在 Linux 中,每个命令在执行时都会打开三个标准的文件描述符:标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。管道命令符正是利用了这一点,将命令 1 的 stdout 连接到命令 2 的 stdin。
- 进程间通信:管道实际上是在两个进程之间建立了一个单向的数据通道,它是由内核管理的缓冲区,因此效率很高。
管道的作用和优点
- 数据流传递:允许将多个简单命令组合在一起,形成复杂的操作流水线。
- 减少中间文件:避免了创建临时文件来存储中间结果。
- 效率高:直接在内存中传递数据,比使用临时文件更高效,减少磁盘 I/O 操作。
常见的使用场景
过滤数据:通过
grep、awk等命令过滤数据。bashcat file.txt | grep "pattern"排序和统计:通过
sort、uniq等命令对数据进行排序和统计。bashcat file.txt | sort | uniq -c格式化输出:使用
cut、awk等命令格式化输出。bashps aux | awk '{print $1, $2, $11}'多级处理:结合多个管道命令进行多级数据处理。
bashcat file.txt | grep "pattern" | sort | uniq
实例解析
查找并排序文件
bashls -l | grep "^d" | sort这里,
ls -l列出详细信息,grep "^d"过滤出目录项,sort对结果进行排序。查找特定进程并终止
bashps aux | grep "process_name" | awk '{print $2}' | xargs kill -9这一命令链首先列出所有进程,使用
grep查找特定进程名,awk提取进程 ID,最后xargs将这些 ID 传递给kill -9进行终止。统计文件中的单词数
bashcat file.txt | tr -s ' ' '\n' | sort | uniq -c | sort -nr这里,
cat显示文件内容,tr将空格转换为换行符,sort对单词进行排序,uniq -c计数,sort -nr按降序排序。
注意事项
- 命令顺序:管道中命令的顺序非常重要,每个命令依次处理数据流。
- 标准输入和输出:多数 Linux 命令支持标准输入(stdin)和标准输出(stdout),这使得它们能够很好地与管道结合使用。
- 性能考虑:管道操作会在内存中传递数据,对于非常大的数据集,可能需要考虑性能和资源消耗问题。
Linux 命令顺序执行
- 场景:想统计某网口 10 秒钟内网络数据包的变化;
ifconfig eth0; sleep 10; ifconfig eth0- 将对应数据进行相减即可得到流量数据;
- 通过
;隔离指令,无论指令执行是否成功,都会往下执行下一句指令
cat /tmp/kernel.log && rm -rf /tmp/kernel.log && touch /tmp/kernel.log- 若文件 kernel.log 不存在,
cat/tmp/kernel.log运行出错,则不会继续执行后续指令 - 可通过
echo$?查看上一句指令执行结果正确性 - 实际场景一般这么写:
cat /tmp/kernel.log; cat /dev/null > /tmp/kernel.log
cat /tmp/kernel.log & rm -rf /tmp/kernel.log如果将指令中的&&换成&呢- => 等价于
cat /tmp/kernel.log &rm -rf /tmp/kernel.log- 即指令
cat /tmp/kernel.log后台执行,同时执行rm -rf /tmp/kernel.log - 一般不这么写
Linux 基础指令回顾
| 命令 | 描述 |
|---|---|
ls -lha | 以人类可读的形式,以列表方式展示文件夹下所有文件 |
| `cat kernel.log | wc -l` |
tail -n20 kernel.log | 输出 kernel.log 文件的最后 20 行内容 |
rm -rf /tmp/log | 删除 /tmp 文件夹下的 log 文件 (夹) |
mv cfg.ini cfg.ini.bak | 将 cfg.ini 文件备份为 cfg.ini.bak |
touch /tmp/cfg.ini | 创建一个 /tmp/cfg.ini 文件或更改其时间信息 |
find ./ -name loc* | 在当前文件夹下查找文件名以 loc 开头的文件 |
shell 脚本用户参数
| 变量 | 描述 |
|---|---|
$0 | 当前 Shell 脚本的名称 |
$# | 总共有几个参数 |
$* | 所有位置的参数值 |
$? | 显示上一次命令的执行返回值 |
$1、$2、$3 | 分别对应着第 N 个位置的参数值 |