这是我正在处理的某些代码的简化版本:
#!/bin/bash
term() {
echo ctrl c pressed!
# perform cleanup - don't exit immediately
}
trap term SIGINT
sleep 100 &
wait $!
如您所见,我想捕获 ctrl c /SIGINT
,并使用自定义功能处理这些功能以执行一些清理操作,而不是立即退出。
但是,按下 ctrl c ,实际上实际上发生的是,尽管我看到ctrl c pressed!
符合预期,但wait
命令也被杀死,我也被杀死。不想发生(我的清理操作的一部分稍后杀死sleep
,但首先做了其他事情(。有什么方法可以防止这种情况,即停止 ctrl c 输入发送到wait
命令?
您可以通过首先使用trap
忽略信号来防止从bash脚本中调用的过程:
#!/bin/bash
# Cannot be interrupted
( trap '' INT; exec sleep 10; )
但是,只有父进程才能等待其孩子,因此wait
是内置的,而不是新过程。因此,这不适用。
相反,只需在中断后重新启动wait
:
#!/bin/bash
n=0
term() {
echo "ctrl c pressed!"
n=$((n+1))
}
trap term INT
sleep 100 &
while
wait "$!"
[ "$?" -eq 130 ] # Sigint results in exit code 128+2
do
if [ "$n" -ge 3 ]
then
echo "Jeez, fine"
exit 1
fi
done
我最终使用了@thatotherguy建议的修改版本:
#!/bin/bash
term() {
echo ctrl c pressed!
# perform cleanup - don't exit immediately
}
trap term SIGINT
sleep 100 &
pid=$!
while ps -p $pid > /dev/null; do
wait $pid
done
这检查该过程是否仍在运行,如果是的,则再次运行wait
。