作业感知外壳与作业不感知外壳执行程序
Posted
技术标签:
【中文标题】作业感知外壳与作业不感知外壳执行程序【英文标题】:Job aware shell vs job unaware shell execution of programs 【发布时间】:2013-12-15 16:36:27 【问题描述】:在阅读 APUE v3 时,更具体地说,我发现自己无法掌握一些东西。 首先,假设我在 UNIX shell 中运行以下管道程序:
cat /etc/passwd | grep -i alex | awk -F : 'print $3' | less
在第一个示例中,假设我正在使用一个作业不知道的 shell (sh)
这本书解释说,在这种情况下,最终的 ps -o pid,ppid,pgid,comm 看起来像这样(假设 shell 的 pid 是 10,它的 ppid 是 5)
PID PPID PGID COMM
10 5 10 sh
11 10 10 less
12 11 10 cat /etc/passwd
13 11 10 grep -i alex
14 11 10 awk -F : 'print $3'
在第二个示例中,假设我们使用的是作业感知 shell (bash):
PID PPID PGID COMM
10 5 10 bash
11 10 11 cat /etc/passwd
12 10 11 grep -i alex
13 10 11 awk -F : 'print $3'
14 10 11 less
问题是,为什么在第二种情况下,进程是 shell 的子进程,而不是最后一个进程的子进程(如第一种情况),并假设 shell 为它的每个子进程接收一个 SIGCHLD,孩子之间不会发生某种竞争条件吗?
PS。对不起,错误的缩进。我现在会尝试修复它 谢谢, 亚历克斯
【问题讨论】:
在这里试图抓住你的问题......你的意思是在孩子们死亡之间的竞争条件,让他们有可能不按时间顺序死亡吗?在任何一种情况下(由shell),命令都会按顺序处理,所以AFAIK这不应该造成问题...... 【参考方案1】:问题是,为什么在第二种情况下,进程是 shell 的子进程,而不是最后一个进程的子进程 [...]
因为这是正确的行为。只有 shell 中的错误可以解释为什么 less
会成为管道中其他进程的父进程。 less
无法处理其他进程的 SIGCHLD,因为它还没有启动它们。 (更重要的是,由于less
中的系统调用因 EINTR 错误而失败,这也会导致问题。)这也意味着除less
之外的所有进程都将由 PID 1 而非 shell 获取,因为它将接收它们的SIGCHLD
.
否则,进程的父子关系与“作业感知外壳”无关。作业感知 shell 做了两件事:它实现作业控制(jobs
、fg
、bg
命令)并将自己设置为会话领导者(使用 setsid() 系统调用),以便将 SIGHUP 自动发送到它(shell)终止时的所有子进程。
[...] 并假设 shell 为它的每个孩子接收一个 SIGCHLD,孩子之间不会发生某种竞争条件吗?
竞态条件是指事情没有按照预期的顺序执行的情况。在这里,没有预期的顺序。大多数过滤器应用程序(像grep
这样的过滤器:从标准输入读取,写入标准输出)一旦在标准输入上看到 EOF 就会终止。通常情况下,管道中的第一个进程可能在最后一个进程看到任何输入时已经终止。这很正常。它们被收割了,但是它们的输出已经被发送到管道中并且会被正常处理。
【讨论】:
以上是关于作业感知外壳与作业不感知外壳执行程序的主要内容,如果未能解决你的问题,请参考以下文章