防止将CTRL + C发送到Bash脚本调用的进程

时间:2019-05-13 20:28:31

标签: bash wait exit keyboard-events sigint

这是我正在处理的某些代码的简化版本:

#!/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!像预期的那样回显,但是{{1 }}命令也会被杀死,这是我不希望发生的(我的清理操作的一部分稍后会杀死wait,但首先会做其他事情)。有什么方法可以防止这种情况发生,即停止将 CTRL + C 输入发送到sleep命令吗?

2 个答案:

答案 0 :(得分:2)

您可以通过先用trap忽略信号来阻止从Bash脚本调用的进程接收sigint:

#!/bin/bash
# Cannot be interrupted
( trap '' INT; exec sleep 10; )

但是,只有父进程可以等待其子进程,因此wait是内置的Shell,而不是新进程。因此,这不适用。

相反,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

答案 1 :(得分:0)

我最终使用了@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