我set -x
使用 ksh88(在 Solaris 10 上)和 ksh93(Fedora 17)测试了一个全局set -x
命令,并且脚本顶部的全局命令没有函数局部范围(即它没有任何局部影响)。
作为一种解决方法,您可以为范围内的所有函数启用本地命令跟踪(在它们被定义之后)以及在它们被调用之前typeset
:
$ cat test.ksh
PS4='$LINENO: '
set -x
function foo {
print Hello
}
bar() {
print World
}
typeset -ft `typeset +f`
foo
bar
ksh88(Solaris 10)下的输出:
$ ksh test.ksh
13: typeset +f
13: typeset -ft bar foo
15: foo
1: print Hello
Hello
16: bar
1: print World
World
排版注释掉了
$ ksh test.ksh
15: foo
Hello
16: bar
World
ksh93(Fedora 17)下的输出:
$ ksh test.ksh
13: typeset +f
13: typeset -ft 'bar()' foo
15: foo
6: print Hello
Hello
16: bar
10: print World
World
排版注释掉了
$ ksh test.ksh
15: foo
Hello
16: bar
10: print World
World
bash 下的输出
typeset
注释掉并print
用 echo 代替:
$ bash test.ksh
15: foo
6: echo Hello
Hello
16: bar
10: echo World
World
(Fedora 17 上的 bash 4.2.39(1))
Fedora 17 上 zsh 5.0.2 下的相同输出。
结论
使用 Ksh 时,只有使用 ksh93 和fnname()
函数定义语法,全局set -x
也具有局部范围。基于typeset -ft
的解决方法是为所有功能启用命令跟踪的一种相对简单的方法。
在 bash(和 zsh)中,全局set -x
按预期工作,即它还具有所有功能的本地范围。
因此,在编写新脚本时,使用 bash 而不是 ksh 可能是更好的选择。
附带说明:bash 可能比 ksh88 更便携——尤其是比 ksh93 更便携。