IT@程序员猿媛Java进阶之路

【深入浅出Linux】Linux管道命令踩坑实录

2019-04-25  本文已影响22人  叫我不矜持

前言

看这个问题前我们要先明白什么是管道。

管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)。
管道命令使用|作为界定符号,管道命令与上面说的连续执行命令不一样。

$ ls -al /etc | less

通过管道将ls -al的输出作为 下一个命令less的输入,方便浏览。

image

正题

接下来进入正题
我想输出xxx.log的每一行,并且在最后输出num:行数。
看看下面的脚本能帮我们做到吗?

#!/bin/bash
#while循环
num=0
cat xxx.log | while read line ;do
    echo $line
    ((num++))
done
echo num:$num

上面的脚本却并不能帮我们做到这一点,为什么?

因为用到了管道的命令,管道两边的命令的执行是依托于开辟进程的方式执行的,因此执行cat xxx.log | while read line ...时,会在当前bash的基础上,开辟两个进程执行上面的两个命令。

上述的过程就是一个fork的概念,什么叫fork?

fork就是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

这里要明白几点:

因而,对于一个变量来说,fork后父子进程各持有一个指针,这个指针在上述例子中指向num内存地址。而在linux中,如果一个进程试图去修改变量时,系统就会把这个变量拷贝一份单独给这个进程,而这个修改操作并不会影响到其他进程中变量的值。而这个原理其实就是Linux的写时复制原理
所以我们在命令中修改的是该子进程对应 num的值,因此对应父进程的num变量无影响。

下一篇博客我会,深度总结一下Linux的写时复制的原理☺

???
上一篇下一篇

猜你喜欢

热点阅读