![“${FUNCNAME[@]}”中的 SIGINT 未清除](https://linux22.com/image/90535/%E2%80%9C%24%7BFUNCNAME%5B%40%5D%7D%E2%80%9D%E4%B8%AD%E7%9A%84%20SIGINT%20%E6%9C%AA%E6%B8%85%E9%99%A4.png)
采用以下脚本,通过键盘输入Ctrl+中断C,如下所示:
$ function a() { echo "Performing"; sleep 10; echo "Performed"; }
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a source
如果我们多次重复SIGINT
while 函数,我们最终会得到这样的场景: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
即使该函数在 中被调用source
,a
也会显示为调用函数。正如您所看到的,所有这些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
。