1. shell执行程序
1.1. 登录shell(Bourne shell)
首先使用不支持作业控制的Bourne shell。
如果我们执行命令:
#ps -o pid,ppid,pgid,sid,comm
# ps -o pid,ppid,pgid,sid,comm &(后台执行)
两种结果都差不多,只是进程ID不一样:
PID | PPID | PGID | SID | COMMAND |
996 | 994 | 996 | 996 | sh |
1820(1822) | 996 | 996 | 996 | ps |
从表中可以看出,ps命令的父进程是shell。shell和ps命令位于同一会话和前台进程组中。因为这种shell不支持作业控制,所以命令2的后台作业没有构成另一个进程组,也没用从后台作业取走控制终端。
如果我们执行命令:
#ps -o pid,ppid,pgid,sid,comm | cat1
# ps -o pid,ppid,pgid,sid,comm | cat1 &(后台执行)
两种结果都差不多,只是进程ID不一样:
PID | PPID | PGID | SID | COMMAND |
996 | 994 | 996 | 996 | sh |
1826(1828) | 996 | 996 | 996 | cat1 |
1827(1829) | 1826(1828) | 996 | 996 | ps |
从表中可以看出,管道线中的最后一个进程是shell的子进程,该管道线中的第一个进程则是最后一个进程的子进程。
如果一个后台进程试图读其控制终端,如下
#cat > temp.txt &
在有作业控制时,后台作业被放在后台进程组,如果后台作业试图读控制终端,则会产生信号SIGTTIN。在没有作业控制时,处理方法是:如果该进程自己没有重定向标准输入,则shell自动将后台进程的标准输入重定向到/dev/null。读/dev/null则产生一个文件结束。这就意味着后台cat进程立即读到文件尾,并正常结束。
如果我们执行命令:
#ps -o pid,ppid,pgid,sid,comm | cat1 | cat2
结果如下:
PID | PPID | PGID | SID | COMMAND |
996 | 994 | 996 | 996 | sh |
1886 | 996 | 996 | 996 | cat2 |
1887 | 1886 | 996 | 996 | ps |
1888 | 1886 | 996 | 996 | cat1 |
从表中可以看出,管道线中的最后一个进程是shell的子进程,而执行该管道线中其它命令的进程则是最后一个进程的子进程。
1.2. Bourne-again shell
Bourne-aggain shell支持作业控制。
如果我们执行命令:
#ps -o pid,ppid,pgid,session,tpgid,comm
PID | PPID | PGID | SESS | TPGID | COMMAND |
1996 | 1896 | 1996 | 1996 | 2008 | bash |
2008 | 1996 | 2008 | 1996 | 2008 | ps |
从表中可以看出,bash将前台作业(ps)放入它自己的进程组(2008)中,ps命令是组长进程,并是改进程组中唯一的进程,此进程组具有控制终端,是前台进程组。注意:sh和bash的会话都没有改变。
如果我们执行命令:
#ps -o pid,ppid,pgid,session,tpgid,comm &
PID | PPID | PGID | SESS | TPGID | COMMAND |
1996 | 1896 | 1996 | 1996 | 1996 | bash |
2008 | 1996 | 2008 | 1996 | 1996 | ps |
从表中可以看出,bash将前台作业(ps)放入它自己的进程组(2008)中,而是一个后台进程组。
如果我们执行命令:
#ps -o pid,ppid,pgid,session,tpgid,comm | cat1
PID | PPID | PGID | SESS | TPGID | COMMAND |
1996 | 1896 | 1996 | 1996 | 2008 | bash |
2008 | 1996 | 2008 | 1996 | 2008 | ps |
2009 | 1996 | 2008 | 1996 | 2008 | cat1 |
从表中可以看出,两个进程ps和cat1都在一个新进程组中(2008),这是一个前台进程组。与sh的区别是,bash是两个进程的父进程。
如果我们执行命令:
#ps -o pid,ppid,pgid,session,tpgid,comm | cat1 &
PID | PPID | PGID | SESS | TPGID | COMMAND |
1996 | 1896 | 1996 | 1996 | 1996 | bash |
2008 | 1996 | 2008 | 1996 | 1996 | ps |
2009 | 1996 | 2008 | 1996 | 1996 | cat1 |
从表中可以看出,两个进程ps和cat1都在一个新进程组中(2008),这是一个后台进程组。