KornShell - 设置“-x” (调试)全局标记?
有没有办法设置调试模式(set -x
) 在全局 KornShell (ksh) 脚本上?目前,我似乎做了类似以下的事情:
a(){
set -x
#commands
}
b(){
set -x
#more commands
}
set-x
a
#commands
b
我真的很想只需要在一处调用 set -x
命令。
注意:这一切都在 AIX 上的 KSH88 中。
例子:
#!/bin/ksh
set -x
a(){
echo "This is A!"
}
b(){
echo "This is B!"
}
a
echo "Outside"
b
dev2:/home/me-> ./testSetX
+ a
This is A!
+ echo Outside
Outside
+ b
This is B!
dev2:/home/me->
Is there a way to set the debug mode (set -x
) on a KornShell (ksh) script globally? Currently it seems I have do something like the following:
a(){
set -x
#commands
}
b(){
set -x
#more commands
}
set-x
a
#commands
b
I would really like to only have to call the set -x
command in one place.
Note: This is all in KSH88 on AIX.
Example:
#!/bin/ksh
set -x
a(){
echo "This is A!"
}
b(){
echo "This is B!"
}
a
echo "Outside"
b
dev2:/home/me-> ./testSetX
+ a
This is A!
+ echo Outside
Outside
+ b
This is B!
dev2:/home/me->
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是 HP-UX 机器上的 ksh88:
看起来确实可以正常工作。我验证了它也可以在第一个函数调用之前的任何地方使用“set -x”。
我迁移到 AIX 系统,并遇到了您所描述的问题。当函数在 AIX ksh88 中定义为
function a {
或a() {
时,set -x
似乎不会结转进入函数局部范围。在同一个 AIX 机器上切换到 ksh93,使用新的function a {
语法声明的函数也不会将外部set -x
携带到内部作用域中。但是,ksh93 的行为类似于 POSIX sh(以及其他平台上的 ksh88)的行为,当函数在旧的a(){< 中定义时,将
set -x
传递给函数。 /代码> 方法。这可能是由于 ksh93 中的向后兼容性所致,当函数以旧方式定义时,它会尝试模拟旧行为。因此,出于调试目的,您可以暂时将解释器切换到 ksh93,如果您不喜欢更长的数组、关联数组、浮点数学、命名空间支持以及大约 10 倍的性能改进,则可以切换回 ksh88。 ksh93带来的执行速度。 ;) 因为对于 AIX 上的 ksh88 来说,答案似乎是“不,你不能这样做”。 :(
This is ksh88 on an HP-UX machine:
It sure looks like that works fine. I validated that it also works with a "set -x" anywhere before the first function call.
I moved to an AIX system, and experienced the problem you described. When functions are defined as either
function a {
ora() {
in AIX ksh88, theset -x
doesn't appear to carry forward into the function-local scope. Switching to ksh93 on the same AIX box, functions declared using the newfunction a {
syntax also don't carry the outerset -x
into the inner scope. However, ksh93 behaves like POSIX sh (and ksh88 on other platforms) used to behave, carrying theset -x
through to the function when the function is defined in the olda(){
method. This is probably due to the backwards compatability in ksh93, where it tries to emulate the old behavior when functions are defined the old way.Therefore, you might be able to temporarily switch the interpreter over to ksh93 for debugging purposes, and then switch back to ksh88 if you don't like having the longer arrays, associative arrays, floating point math, namespace support, and rougly 10x improvement in execution speed which ksh93 brings. ;) Because it looks like the answer is "no, you can't do that" with ksh88 on AIX. :(
我使用 ksh88(在 Solaris 10 上)和 ksh93(Fedora 17)测试了全局
set -x
,并在脚本顶部使用了全局set -x
命令没有函数局部作用域(即它没有任何局部效果)。作为一种解决方法,您可以为作用域内的所有函数(定义之后)以及通过 typeset 调用它们之前启用本地命令跟踪:
ksh88 (Solaris 10) 下的输出:
Typeset 注释掉
ksh93 下的输出 ( Fedora 17):
Typeset 注释掉
bash
typeset
下的输出被注释掉并用 echo 替换print
:(Fedora 17 上的 bash 4.2.39(1))
zsh 5.0 下的相同输出Fedora 17 上的 .2。
结论
使用 Ksh 时,仅使用 ksh93 和
fnname()
函数定义语法,全局set -x
也具有本地作用域。基于typeset -ft
的解决方法是为所有函数启用命令跟踪的相对简单的方法。在 bash(和 zsh)中,全局
set -x
按预期工作,即它还具有所有函数的本地作用域。因此,在编写新脚本时,使用 bash 而不是 ksh 可能是更好的选择。
附带说明一下:bash 可能比 ksh88 更便携——尤其是比 ksh93 更便携。
I tested a global
set -x
with ksh88 (on Solaris 10) and ksh93 (Fedora 17) and with both a globalset -x
command at the top of the script does not have function-local scope (i.e. it does not have any local effects).As a workaround you can enable local command tracing for all functions in scope (after they are defined) and before they are called via
typeset
:Output under ksh88 (Solaris 10):
Typeset commented out
Output under ksh93 (Fedora 17):
Typeset commented out
Output under bash
typeset
commented out andprint
substituted with echo:(bash 4.2.39(1) on Fedora 17)
Same output under zsh 5.0.2 on Fedora 17.
Conclusion
When using Ksh, only with ksh93 and the
fnname()
function definition syntax a globalset -x
also has local scope. Thetypeset -ft
based workaround is a relatively light way to enable command tracing for all functions.In bash (and zsh) a global
set -x
works as expected, i.e. it also has local scope for all functions.Thus, when writing new scripts using bash instead of ksh might be the better alternative because of this.
As a side note: bash is probably even more portable than ksh88 - especially more portable than ksh93.
将其添加到您的 shebang 行:
或将其设置在脚本的顶部:
或从命令行启动脚本:
Add it to your shebang line:
Or set it at the top of your script:
Or start your script from the command line:
“set -x”的行为是 AIX shell 的“特殊性”(更不用说 Brain d...)。
您要求“一种全局设置调试模式的方法”。
以下是我为实现此目的所做的操作:
要启用跟踪,请将脚本环境中的
$set_x
设置为“set -x
”。要在逐个呼叫的基础上对此进行控制,请在呼叫前添加“
set_x='set -x'
”前缀。由于使用了环境变量,因此该方法自然适用于嵌套调用。
所有这些“
$set_x;
”的用法都有点难看,但它适用于所有 shell,并且收益通常大于成本。
AIX shell“特殊性”的另一个示例:
上面应该打印“trapped at file scope”,但什么也不打印。
The behavior of "set -x" is a "peculiarity" of the AIX shell (not to say brain d...).
You asked for "a way to set the debug mode... globally".
Here is what I do to achieve this:
To enable tracing, set
$set_x
in the environment of your script to "set -x
".To control this on a call-by-call basis, prefix the call with "
set_x='set -x'
".Because an environment variable is used, this method naturally works with nested calls.
All those uses of "
$set_x;
" are a bit ugly, but it works with all shells,and the benefit usually outweighs the cost.
Another example of an AIX shell "peculiarity":
The above should print "trapped at file scope", but prints nothing.
请注意,两种类型的函数声明之间的作用域受到影响
。
特别是,ksh 下的类型集无法按照您在前一种情况下所期望的方式工作。在尝试使用递归函数调试脚本时发现的。更多信息请参见:
http://www.dartmouth.edu/~rc/classes /ksh/functions.html
Be aware that scoping is impacted between the two types of function declarations
vs.
In particular, the typset under ksh doesn't work as you would expect in the former case. Found out while trying to debug a script with a recursive function. More here:
http://www.dartmouth.edu/~rc/classes/ksh/functions.html