linux shell中管道发挥的作用是文件描述符重定向,例如 prog1 | prog2 | prog3,管道会将prog1的标准输出重定向为prog2的标准输入,将prog2的标准输出重定向为prog3的标准输入,prog1的标准输入和 prog3的标准输出并没有改变。比如命令"ps -ef | grep -w "nginx""将ps命令的标准输出内容作为grep的输入,两个命令的组合的只输出关于nginx进程的信息。
这里归档两个平时没有想明白的问题:
1、shell管道中程序按什么顺序执行?进程关系是什么样子?
当前有很多的shell程序,实现各不同,有的支持作业控制,代表有:bash(bourne again shell),有的不支持,代表有bourne shell。
prog1 | prog2 | prog3
1)在不支持作业控制shell中,prog3是shell的子进程,而prog1和prog2为prog3的子进程。执行如下图所示
(摘自APUE)
2)对于支持作业控制的shell,prog1、prog2、prog3都为shell的子进程,在bash中的执行顺序为 prog1、prog2、prog3,具体和shell的实现有关。
[root@zhangst ~]# uname -a
Linux zhangst.F14 2.6.35.6-45.fc14.i686 #1 SMP Mon Oct 18 23:56:17 UTC 2010 i686 i686 i386 GNU/Linux
[root@zhangst ~]# ps -o pid,ppid,pgid,session,tpgid,tty,comm | cat | grep -v "*"
PID PPID PGID SESS TPGID TT COMMAND
2667 2664 2667 2667 2689 pts/0 bash
2689 2667 2689 2667 2689 pts/0 ps
2690 2667 2689 2667 2689 pts/0 cat
2691 2667 2689 2667 2689 pts/0 grep
上面的例子中ps、cat、grep三个进程都为bash的子进程,ps进程最先执行,并且三个进程在一个进程组中,ps为组长进程,这个组为前台进程组(TPGID),而bash为后台进程。
2、如何判断管道中程序是否成功执行?某个程序执行失败是否影响其它程序的执行?
1)shell中有一个变量数组PIPESTATUS,保存了上一个执行管道的状态。
echo ${PIPESTATUS[*]};就可以输出所有管道进程的执行状态。
[root@zhangst test]# ./0 | ./1 | ./2 [root@zhangst test]# echo ${PIPESTATUS[*]}
0 1 2 0、1、2三个程序main函数中只包含一条return代码,分别返回 0,1,2。
2)bash中管道程序的执行相互不影响的,参考下面的例子: [root@zhangst test]# ./0 | grep -v | ./2
用法: grep [选项]... PATTERN [FILE]...
试用‘grep --help’来获得更多信息。
2
0 [root@zhangst test]# echo ${PIPESTATUS[*]}
0 2 2 0、2三个程序分别在标准错误输出输出0、2,然后返回0、2
grep -v是不正确的,不能正确执行,但是0和2都正确执行完毕了。
阅读(1608) | 评论(0) | 转发(0) |