“${FUNCNAME[@]}”中的 SIGINT 未清除

“${FUNCNAME[@]}”中的 SIGINT 未清除

采用以下脚本,通过键盘输入Ctrl+中断C,如下所示:

$ function a() { echo "Performing"; sleep 10; echo "Performed"; }
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a source

如果我们多次重复SIGINTwhile 函数,我们最终会得到这样的场景:a

...

$ a
Performing
^C
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a a a a a a a a a source

为了演示这个问题,让我们使用另一个函数 ,b它给出了一个message_error函数,也定义如下:

$ function message_error() {
>   local MESSAGE="$1"
>
>   # FUNCNAME[1], as [0] is `message_error`, gets the calling function
>   echo "[[ ERROR ]] ${FUNCNAME[1]}: $MESSAGE"
>   echo "Rest of the stack: ${FUNCNAME[@]}"
>}
$ function b() { message_error "Oh no"; }
$ b
[[ ERROR ]] b: Oh no
Rest of the stack: message_error b a a a a a a a a a source

即使该函数在 中被调用sourcea也会显示为调用函数。正如您所看到的,所有这些a功能都已退出。但是它们仍然保留在 FUNCNAME 数组中。

为什么是这样? SIGINT删除失败后如何删除?请注意~/.bash_functions,如果获取函数会影响它们解释 SIGINT 的方式,则所有函数均源自大量常用函数。

答案1

由于FUNCNAME是一个只读数组,可能无法删除其中的项目。这似乎unset FUNCNAME可行,但这也破坏了bash的特殊 FUNCNAME 行为。

FUNCNAME可以通过使用以下方法来防止垃圾trap

$ trap : SIGINT
$ function a() {  echo "Performing"; sleep 10; echo "Performed"; } 
$ a
Performing
^C
$ echo %"${FUNCNAME[@]}"%
%%

要禁用上述预防措施,请执行trap - SIGINT

相关内容