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都正确执行完毕了。 |
|