是否在KornShell脚本中结合嵌套函数调用解释了export和typeset之间的区别?

时间:2010-06-04 16:57:29

标签: shell export ksh typeset pdksh

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

#!/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的值将丢失。当通过export声明TEST_VALUE时,当控制返回到外部时,将保留inner中设置的值。

由于外部函数调用内部函数时没有调用新进程,因此我不明白为什么要使用导出以使变量在子函数中保留作用域。另外我注意到排版-x的行为与排版相同,但我希望排版-x等同于导出。

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

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

也许这是一个ksh93缺陷?

2 个答案:

答案 0 :(得分:1)

ksh93手册可以说明typeset

  

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

关于export

  

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

特别是,在函数内部使用导出时,不会恢复任何内容。

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

答案 1 :(得分:1)

您的脚本调用了innerinner_function,但后者未定义。这只是问题中的拼写错误,还是您的实际脚本也出现此错误?

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

尝试将outer_typeset_x的定义从function outer_typeset_x {更改为outer_typeset_x () {,您会看到输出与outer_export的输出相同。