Nic*_*ull 6 bash signals function
执行以下脚本,被键盘输入Ctrl+打断,C如图所示:
$ function a() { echo "Performing"; sleep 10; echo "Performed"; }
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a source
Run Code Online (Sandbox Code Playgroud)
如果我们多次重复SIGINTduring 函数a,我们最终会得到这样的场景:
...
$ a
Performing
^C
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a a a a a a a a a source
Run Code Online (Sandbox Code Playgroud)
为了演示这个问题,让我们有另一个函数,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
Run Code Online (Sandbox Code Playgroud)
即使在 中调用该函数source,也a显示为调用函数。如您所见,所有这些a功能都已退出。但是,它们保留在 FUNCNAME 数组中。
为什么是这样?SIGINT 无法删除它后如何删除它?请注意,所有函数都来自大量常用函数~/.bash_functions,如果这些函数的来源会影响它们解释 SIGINT 的方式。
由于FUNCNAME是只读数组,因此可能无法删除其中的项目。这似乎unset FUNCNAME可行,但这也破坏了bash的特殊 FUNCNAME 行为。
FUNCNAME可以通过使用以下方法来防止垃圾trap:
$ trap : SIGINT
$ function a() { echo "Performing"; sleep 10; echo "Performed"; }
$ a
Performing
^C
$ echo %"${FUNCNAME[@]}"%
%%
Run Code Online (Sandbox Code Playgroud)
要禁用上述预防措施,请执行trap - SIGINT。
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |