2

我遇到了 KornShell (ksh) 脚本在 ksh88 和 ksh93 上以不同方式运行的问题,其中调用函数的函数处理方式不同,使用排版和导出声明的变量。这是一个突出差异的示例脚本:

#!/bin/ksh
# example.ksh: highlights differences between typeset and export on ksh93
function inner
{
  echo "  Inside inner, before assignment, TEST_VALUE=[$TEST_VALUE]"
  TEST_VALUE=abc
  echo "  Inside inner, after assignment, TEST_VALUE=[$TEST_VALUE]"
}
function outer_typeset
{
  typeset TEST_VALUE
  echo "Inside outer_typeset, before call of inner, TEST_VALUE=[$TEST_VALUE]"
  inner
  echo "Inside outer_typeset, after call of inner, TEST_VALUE=[$TEST_VALUE]"
}
function outer_typeset_x
{
  typeset -x TEST_VALUE
  echo "Inside outer_typeset_x, before call of inner, TEST_VALUE=[$TEST_VALUE]"
  inner
  echo "Inside outer_typeset_x, after call of inner, TEST_VALUE=[$TEST_VALUE]"
}
function outer_export
{
  export TEST_VALUE
  echo "Inside outer_export, before call of inner, TEST_VALUE=[$TEST_VALUE]"
  inner
  echo "Inside outer_export, after call of inner, TEST_VALUE=[$TEST_VALUE]"
}

outer_typeset
unset TEST_VALUE
echo
outer_typeset_x
unset TEST_VALUE
echo
outer_export

在运行 ksh93 的 Linux 机器上运行时的结果如下:

$ echo ${.sh.version}
Version M 1993-12-28 r

$ ./example.ksh
Inside outer_typeset, before call of inner, TEST_VALUE=[]
  Inside inner, before assignment, TEST_VALUE=[]
  Inside inner, after assignment, TEST_VALUE=[abc]
Inside outer_typeset, after call of inner, TEST_VALUE=[]

Inside outer_typeset_x, before call of inner, TEST_VALUE=[]
  Inside inner, before assignment, TEST_VALUE=[]
  Inside inner, after assignment, TEST_VALUE=[abc]
Inside outer_typeset_x, after call of inner, TEST_VALUE=[]

Inside outer_export, before call of inner, TEST_VALUE=[]
  Inside inner, before assignment, TEST_VALUE=[]
  Inside inner, after assignment, TEST_VALUE=[abc]
Inside outer_export, after call of inner, TEST_VALUE=[abc]

如您所见,当 TEST_VALUE 被排版时,当控制权返回到外部函数时,内部设置的 TEST_VALUE 的值会丢失。当通过导出声明 TEST_VALUE 时,当控制权返回到外部时,内部设置的值将被保留。

由于在外部函数调用内部函数时没有调用新进程,所以我不明白为什么要使用 export 以使变量保持子函数中的范围。我还注意到 typeset -x 的行为与 typeset 相同,而我希望 typeset -x 等同于导出。

当我在运行 ksh88(AIX、Solaris、HP-UX)或 pdksh (Linux) 或 MKS ksh 的机器上运行此程序时,typeset、typeset -x 和 export 在此示例中的行为相同。

现在我已经将排版更改为导出,以便为使用在 ksh88 上开发和测试的类似代码的程序提供 ksh93 上的兼容性。

也许这是一个 ksh93 缺陷?

4

2 回答 2

1

ksh93 手册有这样的说法typeset

在使用函数名称语法定义的函数内部调用时,会创建变量 vname 的新实例,并在函数完成时恢复变量的值和类型。

这关于export

给定的名称被标记为自动导出到随后执行的命令的环境中。

特别是,当您在函数中使用 export 时,不会恢复任何内容。

这似乎typeset是为了提供其他语言中“过程局部变量”提供的功能。我不会称之为设计缺陷。

于 2010-06-04T18:53:46.017 回答
1

您的脚本有调用innerinner_function但后者未定义。这只是问题中的错字还是您的实际脚本也有此错误?

您在输出中显示的行为是正确的。

尝试更改outer_typeset_xfrom function outer_typeset_x {to的定义,outer_typeset_x () {您会发现它的输出与 for 相同outer_export

于 2010-06-04T19:48:54.853 回答