我又开始涉足 Bash 中的陷阱了。我刚刚注意到 RETURN 陷阱不会启动函数。
$ trap 'echo ok' RETURN
$ f () { echo ko; }
$ f
ko
$ . x
ok
$ cat x
$
正如您所看到的,它按预期进行,以获取空文件x
。
Bashman
是这样的:
如果 sigspec 为 RETURN,则每次使用 .shell 函数或脚本执行时都会执行命令 arg。或源内置程序完成执行。
那我还缺少什么呢?
我有 GNU bash,版本 4.4.12(1)-release (x86_64-pc-linux-gnu)。
答案1
据我了解,我的问题中的文档片段有一个例外。片段是:
如果 sigspec 为 RETURN,则每次使用 .shell 函数或脚本执行时都会执行命令 arg。或源内置程序完成执行。
异常描述如下:
函数及其调用者之间 shell 执行环境的所有其他方面都是相同的,但有以下例外:DEBUG 和 RETURN 陷阱(请参阅下面的 SHELL BUILTIN COMMANDS 下内置陷阱的描述)除非函数被赋予了 Trace 属性(请参阅下面的内部声明的描述)或者已使用 set 内置函数启用了 -o functrace shell 选项,否则不会被继承(在这种情况下,所有函数都会继承 DEBUG 和 RETURN 陷阱),并且不会继承 ERR 陷阱,除非已启用 -o errtrace shell 选项。
至于functrace
,可以用 的 来打开typeset
它-t
:
-t 为每个名称赋予跟踪属性。跟踪函数从调用 shell 继承 DEBUG 和 RETURN 陷阱。 Trace 属性对于变量没有特殊含义。
也set -o functrace
有窍门。
这是一个例子。
$ trap 'echo ko' RETURN
$ f () { echo ok; }
$ cat y
f
$ . y
ok
ko
$ set -o functrace
$ . y
ok
ko
ko
至于declare
,又是一个-t
选项:
-t 为每个名称赋予跟踪属性。跟踪函数从调用 shell 继承 DEBUG 和 RETURN 陷阱。 Trace 属性对于变量没有特殊含义。
还extdebug
可以启用函数跟踪,如伊卡丘的回答。
答案2
在 Bash 4.4 上,它似乎只适用于extdebug
启用的函数,尽管我看不到文档中提到的内容。
$ cat ret.sh
trap "echo ret" RETURN
foo() { echo "$1"; }
foo "without extdebug"
shopt -s extdebug
foo "with extdebug"
$ bash ret.sh
without extdebug
with extdebug
ret
$ bash --version |head -1
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
在 Bash 4.3 中,它似乎根本不适用于函数。