我的脚本的目的是计算file
.我知道我可以使用wc
示例,但本练习的目的是了解 Linux 中的进程和管道。
在我的终端上执行的脚本:
C=0; cat file | while read line ; do C=$[ $C + 1 ] ; done ; echo $C
我总是得到0
或任何我初始化C
变量的数字。
在我的教科书中,他们解释了这种行为,说对于每个管道,都会创建一个新的子进程,它继承所有父亲变量,但当孩子死亡时,父亲仍然“看到”他的旧值。我对此表示同意。
我不明白的是,我只看到一条管道,介于C=0; cat file
和之间while read line ; do C=$[ $C + 1 ] ; done ; echo $C
。所以我猜测第二部分echo
也是由孩子执行的,那么为什么它会打印错误的值呢?子级不应该增加C
变量并打印正确的值,因为它属于同一管道吗?
答案1
我不明白的是,我只看到一条管道,介于
C=0; cat file
和之间while read line ; do C=$[ $C + 1 ] ; done ; echo $C
。
不,它不是这样解析的。你实际上有三个“管道”:
C=0
cat file | while read line ; do C=$[ $C + 1 ] ; done
echo $C
(当然,第一个和第三个是退化的单命令管道,但从技术上讲它们仍然是这样。管道是的序列一个或多个命令由控制运算符“|”分隔)
换句话说,第一个和最后一个分号分隔管道。介于while
和之间的done
,因为它们是while
复合命令。
一个没有任何复合命令的简单示例:
$ echo hello | tr a-z x ; echo you | tr a-z y
xxxxx
yyy
在这里,我们可以很容易地看到,只hello
转到第一个tr
,并且只you
转到第二个tr
,即分号分隔管道。
问题为什么我的变量在一个“while read”循环中是本地变量,但在另一个看似相似的循环中却不是?包含多种执行您尝试执行的操作的方法,以便能够输出C
循环更新的值。