【问题标题】:KornShell - Set "-x" (debug) flag globally?KornShell - 全局设置“-x”(调试)标志?
【发布时间】:2011-01-17 10:12:05
【问题描述】:

有没有办法在 KornShell (ksh) 脚本上全局设置调试模式 (set -x)?目前看来我已经做了以下事情:

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->

【问题讨论】:

  • 这很奇怪。我还刚刚在我的一个 AIX 系统上的 ksh88(和 ksh93)中尝试了它,并且确实得到了所描述的行为。但是我的 HP-UX 系统上的 ksh88 可以像你想要的那样工作。我修改了答案以反映结果。
  • fyi,Solaris 10 上的 ksh88 /usr/bin/ksh 也显示了所描述的行为(无全局影响 set -x)。

标签: shell debugging scripting ksh script-debugging


【解决方案1】:

这是 HP-UX 机器上的 ksh88:

me@host ..dev/
$ cat ./test/verbose
#!/bin/ksh
set -x

hello() {
  print $1
}

hello kapow!
exit

me@host..dev/
$ ./test/verbose    
+ hello kapow!
+ print kapow!
kapow!
+ exit

确实看起来这样可以正常工作。我在第一次函数调用之前验证了它也可以在任何地方使用“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 以进行调试,然后如果您不喜欢更长的数组、关联数组、浮点数学、命名空间支持和粗略,则可以切换回 ksh88 ksh93 带来的执行速度提高了 10 倍。 ;) 因为对于 AIX 上的 ksh88,答案看起来是“不,你不能这样做”。 :(

【讨论】:

  • 感谢伟大的研究,我会看到升级到 ksh93,但在我的环境中......
  • IBM 在同一个包中提供了 ksh93 和 ksh88(至少在我看过的 AIX 5.3 和 6.1 系统上是这样);该二进制文件仅称为 ksh93。如果这有帮助... :)
【解决方案2】:

将其添加到您的 shebang 行:

#!/bin/ksh -x

或将其设置在脚本的顶部:

#!/bin/ksh
set -x

或者从命令行启动你的脚本:

ksh -x script_name

【讨论】:

  • 不幸的是,这些都不适合我。我只看到方法的名称。可能是因为我用的是ksh88。
【解决方案3】:

我使用 ksh88(在 Solaris 10 上)和 ksh93(Fedora 17)测试了全局 set -x,并且脚本顶部的全局 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 更便携。

【讨论】:

  • +1 这对我在 AIX 5.3 和 7.1 上使用 ksh88 有效。如果有更多关于排版如何工作的解释,那就太好了。
【解决方案4】:

“set -x”的行为是 AIX shell 的“特殊性”(不是说大脑...)。

您要求“一种设置调试模式的方法......全局”。 这是我为实现这一目标所做的工作:

set_x="${set_x-:}"; # Defaults to ":" (NOOP) unless already non-empty
# Using ":" instead of "" makes termination via semicolon work,
# which in turn allows inlining, especially when using SSH.
# Alternatively, if tracing should be on by default:
#set_x="${set_x-set -x}"; # Defaults to "set -x" unless already non-empty

$set_x; # Apply to file scope

f() {
    $set_x; # Apply to local scope
    echo working...;
}
main() {
    $set_x; # Apply to local scope
    f;
    ssh localhost $set_x\; hostname; # Apply to remote shell scope
    ssh localhost "set_x=\"$set_x\" foo"; # Apply to foo called in remote shell
}
main;

要启用跟踪,请将脚本环境中的$set_x 设置为“set -x”。 要在逐个呼叫的基础上进行控制,请在呼叫前加上“set_x='set -x'”。 因为使用了环境变量,所以这种方法自然适用于嵌套调用。

$set_x;”的所有这些用法有点难看,但它适用于所有 shell, 而且收益通常大于成本。

AIX shell“特殊性”的另一个示例:

set -e;
trap "echo trapped at file scope" EXIT;
f() { return 1; }
main() { f; }
main;

上面应该打印“被困在文件范围内”,但什么也不打印。

【讨论】:

    【解决方案5】:

    请注意,两种类型的函数声明会影响范围

    a() {
    }
    

    对比

    function a {
    }
    

    特别是,在前一种情况下,ksh 下的 typset 无法正常工作。在尝试使用递归函数调试脚本时发现。更多内容:

    http://www.dartmouth.edu/~rc/classes/ksh/functions.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多