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

我有一个应该捕获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_COMMAND重新运行最后一个命令(例如读取).

prompt () {
    read -p 'Prompting: '
}
reprompt () {
    echo >&2
    eval "$BASH_COMMAND"
}
trap "reprompt" INT
prompt

在这种情况下,* BASH_COMMAND *计算读取-p’提示:’.然后需要使用eval重新处理该命令.如果你没有评估它,你可能会得到奇怪的引用问题.因人而异.

使用FUNCNAME重新运行调用堆栈中的上一个函数.

prompt () {
    read -p 'Prompting: '
}
reprompt () {
    echo >&2
    "${FUNCNAME[1]}"
}
trap "reprompt" INT
prompt

在此示例中,FUNCNAME [1]扩展为提示,这是堆栈中的上一个函数.我们只需要递归地再次调用它,根据需要多次.

点赞