[原创]Bash中管道(|)与重定向(< >)的一个区别

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
surejim
帖子: 19
注册时间: 2008-03-27 17:02

[原创]Bash中管道(|)与重定向(< >)的一个区别

#1

帖子 surejim » 2009-03-05 16:27

管道触发两个子进程执行"|"两边的程序;而重定向是在一个进程内执行。

举例一:
* 对于管道
在bash下执行命令:tail -f num.txt | grep aaa

此时在另一个shell窗口中输入:ps aux | grep tail
pxj 5026 0.0 0.0 3300 732 pts/1 S+ 15:27 0:00 tail -f num.txt
pxj 5031 0.0 0.0 3220 772 pts/0 R+ 15:27 0:00 grep tail
再输入:ps aux | grep aa
pxj 5027 0.0 0.0 3220 768 pts/1 S+ 15:27 0:00 grep aaa
pxj 5039 0.0 0.0 3220 760 pts/0 R+ 15:27 0:00 grep aa

由上面的输出可见tail -f num.txt的PID=5026,grep aaa的PID=5027,说明是两个不同的进程。

* 对于重定向: tail -f num.txt > /tmp/num
执行:ps aux | grep tail
pxj 6041 0.0 0.0 3300 740 pts/0 S+ 16:06 0:00 tail -f num.txt

只有一个进程。


举例二(摘自<高级 Bash 脚本编程指南>):
作为子进程的运行的管道,不能够改变脚本的变量.
1 variable="initial_value"
2 echo "new_value" | read variable
3 echo "variable = $variable" #variable = initial_value

举例三:
* 代码一:
while read line
do
a[$line]='a'
echo "in while:"${a[$line]}
done < num.txt

#输出数组中所有元素
echo ${a[*]}

代码一的输出:
in while:a
in while:a
in while:a
in while:a
in while:a
in while:a
==a a a a a a #注意:使用重定向,数组的元素得以输出。

* 代码二:
cat num.txt | while read line
do
a[$line]='a'
echo "in while:"${a[$line]}
done

echo "=="${a[*]}
代码二的输出:
in while:a
in while:a
in while:a
in while:a
in while:a
in while:a
== #注意:使用管道,数组的元素为空。

因为管道是在子进程中执行,所以当子进程退出之后,给数组a赋的值也随着子进程的退出而消失了。
因而,代码二最后一行看到的数组a并不是while循环中的数组a。


参考文献:
<高级 Bash 脚本编程指南>


以为内容为个人的一点理解,本人水平有限,如有差错,还请高手斧正,谢谢! :em06
希望有高手能全面地讲讲管道与重定向的区别。
头像
Rubisco
帖子: 102
注册时间: 2010-12-20 18:19
系统: ubuntu12.04

Re: [原创]Bash中管道(|)与重定向(< >)的一个区别

#2

帖子 Rubisco » 2012-12-26 19:33

刚接触一点>,看到了你的文章,虽然不太懂,但是由衷的感谢你的总结
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: [原创]Bash中管道(|)与重定向(< >)的一个区别

#3

帖子 枫叶饭团 » 2012-12-26 20:25

原来如此,学习了。。。写入笔记
回复