Linux bash脚本中的父进程和子进程关系

时间:2014-01-18 14:53:00

标签: linux bash shell process pid

我对linux进程有疑问,我无法弄清楚 这个问题来自“Advanced Bash Script”一书,代码在这里:(我简化了它)

#! /bin/bash
# spawn.sh
sleep 1
sh $0   # fork a child process here and into infinite loop

exit 0  # the script will never come here

当我在shell中运行 ./ spawn.sh 时,进程将被卡在那里,并且在一段时间后会有很多“sh spawn.sh”进程。 /> 我认为流程之间的关系现在就像:

./ spawn.sh process(pid:10000)--->子进程(pid:10001)--->子进程(pid:1002)--->子进程(pid:1003)--->等等

当我在命令行管理程序中推送Control-C时,父进程已结束,并且其所有子进程都已结束。这是我无法理解的地方。为什么所有的孩子都处死了?我认为流程之间的关系应该是:

init(pid:1)--->子进程(pid:10001)--->子进程(pid:1002)--->子进程(pid:1003)--->等等

但事实是好像父进程在结束时向其子进程发送信号,从而导致所有子进程逐个消亡。这是正常的还是shell脚本的一个特性?

非常感谢你。

3 个答案:

答案 0 :(得分:1)

  

当我在Shell中推送Control-C时,父进程结束了,并且   它的所有子进程也都结束了。这是我不能的地方   了解。为什么所有的孩子都处死了

当您按Ctrl-C时,SIGINT不仅会发送到父进程,还会发送到整个进程组。这意味着所有三个进程都会获得一个SIGINT,因此它们会死掉。要查看此操作,请添加

trap "process $$ exiting" INT

快速查看孩子对父母的死亡没有反应的方法是让一个脚本产生一个孩子然后杀死父母。

答案 1 :(得分:0)

Control-C正在杀死最近的孩子,而不是原始的shell。当sh $0退出时,下一行代码会导致当前shell退出,这会导致一系列已完成的进程一直返回到原始父进程。

答案 2 :(得分:0)

我想我现在知道答案了。这是因为Control-C不仅会将SIGINT发送给shell脚本进程,还会发送它的子进程。由于这些过程不会捕获SIGINT,因此它们结束了 命令 kill -2 与Ctrl-C不同,有关详细信息,请参阅:http://ajhaupt.blogspot.com/2011/01/whats-difference-between-ctrl-c-and.html
谢谢大家帮助我:)。