[shell/linux] Shell 管道流机制及原理

缘起:shell 管道流

  • Shell 有一种功能,就是可以将两个或者多个命令(程序或者进程)连接到一起,把一个命令的输出作为下一个命令的输入,以这种方式连接的两个或者多个命令就形成了管道(pipe)。

  • 那么,shell 管道流的原理是如何的?以多个管道流命令(cat xxx.log | grep -i "keyword" | jq -r "keyword2")为例,每个管道流是一次性读取全部的,还是各个管道逐行读取逐行流动?

原理释疑

  • 在Unix和类Unix系统中,管道pipe)是一种进程间通信机制

它允许一个命令的输出直接作为另一个命令的输入。

  • 管道流的原理是基于流式处理的,而不是一次性读取全部数据

这意味着数据在管道中是逐行(或逐块)流动的,而不是一次性读取整个文件或数据流。

  • 重定向管道的区别:
  • 重定向操作符>将命令与文件连接起来,用文件来接收命令的输出;
  • 管道符|将命令与命令连接起来,用第二个命令来接收第一个命令的输出。
command > file
command1 | command1

案例分析

//利用shell管道流机制,逐行读取 log 文件,过滤抽取出目标日志行,并基于 json 库(jq)解析出 keyword2 属性的值
> cat xxx.log | grep -i "keyword" | jq -r "keyword2"
30805605
33570848
31723789
30823832
32299559
30122921
31429771
34140832
32699584
33846995
  • cat xxx.log:cat命令读取文件xxx.log的内容,并将其输出到标准输出(stdout)。cat通常会逐行读取文件内容,然后将每一行发送到管道。
  • grep -i "keyword":grep命令从管道接收cat的输出。它逐行读取这些数据,并检查每一行是否包含指定的关键词(不区分大小写)。如果找到匹配的行,grep将这些行发送到下一个管道。
  • jq -r "keyword2":jq命令从管道接收grep的输出。它逐行处理这些数据,并根据提供的jq表达式进行进一步处理。处理后的结果被输出到标准输出。

管道流机制的优点

  • 内存效率:由于管道流是逐行处理的,它不需要一次性将整个文件或数据流加载到内存中。这对于处理大文件或大量数据非常有用,因为它减少了内存的使用。
  • 性能:逐行处理可以提高性能,因为命令可以并行执行。例如,grep可以在cat还在读取文件时就开始处理数据,而不是等待整个文件被读取完毕。
  • 灵活性:管道流允许将多个简单的命令组合成复杂的处理流程,使得脚本编写更加灵活和简洁。

注意事项

  • 缓冲:虽然管道流是逐行处理的,但在某些情况下,命令可能会使用缓冲机制来提高性能。这意味着数据可能不会立即从一个命令传递到下一个命令,而是会在缓冲区中累积到一定量后再传递。
  • 错误处理:在使用管道流时,需要注意错误处理。如果管道中的某个命令失败,后续命令可能仍然会继续执行,这可能导致不期望的结果。因此,在编写复杂的管道命令时,可能需要额外的错误检查和处理逻辑。

总的来说,管道流的逐行处理机制使得Unix命令行工具能够高效、灵活地处理数据流,是Unix哲学中“一切皆文件”和“组合简单工具”的体现。

X 参考文献

posted @ 2025-01-07 10:47  千千寰宇  阅读(13)  评论(0编辑  收藏  举报