我有一个想要监视另一个程序的 Bourne shell (/bin/sh) 脚本(用于可移植性)。它应该启动另一个程序,然后等待它退出。当第二个程序退出时,它会做一些最后的工作并自行退出。问题是脚本还需要响应信号(例如 USR2)并在这些信号出现时做一些工作。
我天真的实现是:
#! /bin/sh
echo $$
trap 'echo Respond to USR2' USR2
/bin/sleep 120 &
pid=$!
wait $pid
echo $pid exited with $?
echo Doing final cleanup
这行不通。如果我发送 shell SIGUSR2,陷阱会按预期触发,但等待也会结束,返回 140。 /bin/sleep 继续其愉快的方式。典型输出:
28849
Respond to USR2
28850 exited with 140
Doing final cleanup
这种行为在 dash 和 bash 之间是一致的,我可以方便地访问这两个 Bourne shell 衍生物。
我目前的工作是旋转循环等待子 PID 消失,用 kill 进行探测。自旋循环似乎很浪费,并且如果 PID 被快速重用,我的脚本可能会错误地等待错误进程的窗口扩大。
#! /bin/sh
echo $$
trap 'echo Respond to USR2' USR2
/bin/sleep 15 &
pid=$!
while /bin/kill -0 $pid 2> /dev/null; do
echo waiting...
sleep 2
done
echo Doing final cleanup
考虑到我的目标是同时等待另一个进程退出并能够响应信号,是否有更好的解决方案?