Skip to content

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 -l
  • find /path/to/directory -type f —— 查找指定目录中的所有文件。
  • grep "\.jpg$" —— 从 find 命令的输出中筛选出以 .jpg 结尾的文件名。
  • wc -l —— 计算通过管道传递来的行数,即 .jpg 文件的数量。

工作原理

  1. 标准输出和标准输入:在 Linux 中,每个命令在执行时都会打开三个标准的文件描述符:标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。管道命令符正是利用了这一点,将命令 1 的 stdout 连接到命令 2 的 stdin。
  2. 进程间通信:管道实际上是在两个进程之间建立了一个单向的数据通道,它是由内核管理的缓冲区,因此效率很高。

管道的作用和优点

  1. 数据流传递:允许将多个简单命令组合在一起,形成复杂的操作流水线。
  2. 减少中间文件:避免了创建临时文件来存储中间结果。
  3. 效率高:直接在内存中传递数据,比使用临时文件更高效,减少磁盘 I/O 操作。

常见的使用场景

  1. 过滤数据:通过 grepawk 等命令过滤数据。

    bash
    cat file.txt | grep "pattern"
  2. 排序和统计:通过 sortuniq 等命令对数据进行排序和统计。

    bash
    cat file.txt | sort | uniq -c
  3. 格式化输出:使用 cutawk 等命令格式化输出。

    bash
    ps aux | awk '{print $1, $2, $11}'
  4. 多级处理:结合多个管道命令进行多级数据处理。

    bash
    cat file.txt | grep "pattern" | sort | uniq

实例解析

  1. 查找并排序文件

    bash
    ls -l | grep "^d" | sort

    这里,ls -l 列出详细信息,grep "^d" 过滤出目录项,sort 对结果进行排序。

  2. 查找特定进程并终止

    bash
    ps aux | grep "process_name" | awk '{print $2}' | xargs kill -9

    这一命令链首先列出所有进程,使用 grep 查找特定进程名,awk 提取进程 ID,最后 xargs 将这些 ID 传递给 kill -9 进行终止。

  3. 统计文件中的单词数

    bash
    cat file.txt | tr -s ' ' '\n' | sort | uniq -c | sort -nr

    这里,cat 显示文件内容,tr 将空格转换为换行符,sort 对单词进行排序,uniq -c 计数,sort -nr 按降序排序。

注意事项

  1. 命令顺序:管道中命令的顺序非常重要,每个命令依次处理数据流。
  2. 标准输入和输出:多数 Linux 命令支持标准输入(stdin)和标准输出(stdout),这使得它们能够很好地与管道结合使用。
  3. 性能考虑:管道操作会在内存中传递数据,对于非常大的数据集,可能需要考虑性能和资源消耗问题。

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.logwc -l`
tail -n20 kernel.log输出 kernel.log 文件的最后 20 行内容
rm -rf /tmp/log删除 /tmp 文件夹下的 log 文件 (夹)
mv cfg.ini cfg.ini.bakcfg.ini 文件备份为 cfg.ini.bak
touch /tmp/cfg.ini创建一个 /tmp/cfg.ini 文件或更改其时间信息
find ./ -name loc*在当前文件夹下查找文件名以 loc 开头的文件

shell 脚本用户参数

变量描述
$0当前 Shell 脚本的名称
$#总共有几个参数
$*所有位置的参数值
$?显示上一次命令的执行返回值
$1$2$3分别对应着第 N 个位置的参数值