linux shell中的管道执行

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的子进程。执行如下图所示
linux shell中的管道执行_第1张图片
(摘自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都正确执行完毕了。

原文:http://blog.chinaunix.net/uid-21843265-id-3132119.html

你可能感兴趣的:(linux,shell)