我遇到了 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 缺陷?