父进程在收到来自孩子的信号后停止等待?

时间:2015-04-15 21:27:34

标签: shell sh

我在shell中编写了一个脚本,遇到了一个我不完全理解的行为。即这个脚本:

#!/bin/sh

# traps SIGINT and only echoes
trap 'trapINT' INT
trapINT() {
  echo "Child calling."
}

# sleeps for i seconds, then prints i and
# sends a SIGINT to parent
sleep_and_echo() {
  sleep $1
  echo $1
  kill -INT $2
} 

# Main loop, spawn three children
for i in $(seq 1 3); do
  sleep_and_echo $i $$ &
  echo "Process no. $i with PID $! executed."
done

# wait for all the children to finish?
wait

echo "Waiting done."
exit

起初我认为,对于每个孩子,父母将接收一个SIGINT,将陷阱而不是中断,然后等待孩子们结束,然后回应他的孩子结束并将结束自己。

然而,这个过程确实存在一个问题,似乎在从他的第一个孩子(i = 1)收到第一个SIGINT后放弃了他的等待。这是脚本的终端摘要:

ashen@SummerParadise:~/School/UNIX/8-DU$ ./examp.sh
Process no. 1 with PID 3904 executed.
Process no. 2 with PID 3905 executed.
Process no. 3 with PID 3906 executed.
1
child calling
Waiting done.
ashen@SummerParadise:~/School/UNIX/8-DU$ 2
./examp.sh: 11: kill: No such process

3
./examp.sh: 11: kill: No such process

^C

有人可以解释这种行为吗?我想做一个等待他的孩子的脚本,并且只允许最多1美元同时运行,如果一个人结束并发出另一个信号,则接收信号,但事实是他在陷阱例程破坏了这个想法后停止等待。

谢谢

1 个答案:

答案 0 :(得分:0)

我无法在posix文档中找到一个很好的描述,但是bash手册页说:

当bash正在等待异步命令时        通过等待内置,接收已设置陷阱的信号将导致等待内置        在退出状态大于128时立即返回,之后立即执行陷阱。

所以你可以通过这样做来重试等待:

(exit 129)
while $? -gt 128; do wait; done