在bash中陷阱返回后如何重新提示?

在bash中陷阱返回后如何重新提示?,bash,shell,signals,Bash,Shell,Signals,我有一个脚本,应该是陷阱SIGTERM和SIGTSTP。这是我在主块中看到的: trap 'killHandling' TERM 在函数中: killHandling () { echo received kill signal, ignoring return } 。。。和SIGINT类似。问题在于用户界面。脚本会提示用户输入一些内容,如果在脚本等待输入时出现SIGTERM或SIGINT,则会造成混乱。以下是这种情况下的输出: Enter something: #

我有一个脚本,应该是陷阱SIGTERM和SIGTSTP。这是我在主块中看到的:

trap 'killHandling' TERM
在函数中:

killHandling () {
    echo received kill signal, ignoring
    return
}
。。。和SIGINT类似。问题在于用户界面。脚本会提示用户输入一些内容,如果在脚本等待输入时出现SIGTERM或SIGINT,则会造成混乱。以下是这种情况下的输出:

Enter something:     # SIGTERM received
received kill signal, ignoring

      # shell waits at blank line for user input, user gets confused
      # user hits "return", which then gets read as blank input from the user
      # bad things happen because of the blank input
我肯定见过更优雅地处理这个问题的脚本,比如:

Enter something:     # SIGTERM received
received kill signal, ignoring
Enter something:     # re-prompts user for user input, user is not confused
实现后者的机制是什么?不幸的是,我不能简单地更改陷阱代码来执行重新提示,因为脚本会提示用户做一些事情,并且提示的内容取决于上下文。必须有比编写上下文相关的陷阱函数更好的方法


如果有人给我指点,我将不胜感激。谢谢

这些方法并不十分健壮——例如,在第一个陷阱之后,它将CTRL-C作为字符处理的方式存在一些问题——但它们都处理您定义的用例

使用BASH_命令重新运行最后一个命令(例如read)。 在本例中,*BASH_命令*的计算结果为
read-p'提示:'
。然后需要使用eval重新处理该命令。如果你不评估它,你可能会遇到奇怪的引用问题。YMMV

使用FUNCNAME重新运行调用堆栈中的上一个函数。
在本例中,FUNCNAME[1]扩展为
提示符
,这是堆栈中的上一个函数。我们只是根据需要多次递归调用它。

CodeGnome给出的答案很有效,但正如他所指出的,它并不健壮;第二个控件-c会导致不良行为。通过更好地利用代码中现有的输入验证,我最终解决了这个问题。因此,我的中断处理代码如下所示:

killHandling () {
   echo received kill signal, ignoring
   echo "<<Enter>> to continue"
   return
}
killHandling(){
回波接收到终止信号,忽略
回声“继续”
返回
}
现在光标仍在一个空白行等待用户输入,但用户不会感到困惑,并按提示点击“回车”键。然后,脚本的输入验证检测到输入了一个空行,该空行被视为无效输入,并再次提示用户输入内容


我仍然感谢CodeGnome的建议,从中我学到了一些东西。我为延迟发布此答案而道歉

谢谢CodeGnome!我认为你的第一个建议在我的具体情况下会很有效。我试试看。
prompt () {
    read -p 'Prompting: '
}
reprompt () {
    echo >&2
    "${FUNCNAME[1]}"
}
trap "reprompt" INT
prompt
killHandling () {
   echo received kill signal, ignoring
   echo "<<Enter>> to continue"
   return
}