是否有解释导出和排版与 KornShell 脚本中的嵌套函数调用相结合的区别?
我遇到了 KornShell (ksh) 脚本在 ksh88 和 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 时,当控制权返回到外部时,内部设置的值将被保留。
由于当外部函数调用内部函数时没有调用新的进程,因此我不明白为什么应该使用导出以使变量在子函数中保持作用域。我还注意到 typeset -x 的行为与 typeset 相同,而我希望 typeset -x 相当于导出。
当我在运行 ksh88(AIX、Solaris、HP-UX)或 pdksh (Linux) 或 MKS ksh 的计算机上运行此程序时,排版、排版 -x 和导出在本示例中的行为相同。
现在,我已将排版更改为导出,以便为使用在 ksh88 上开发和测试的类似代码的程序提供 ksh93 上的兼容性。
也许这是 ksh93 的缺陷?
I have encountered an issue with KornShell (ksh) scripts running differently on ksh88 & ksh93 wherein functions which call functions handle differently, variables declared with typeset and export. Here is an example script that highlights the difference:
#!/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
The result when run on a Linux box running ksh93 follows:
$ 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]
As you can see when TEST_VALUE is typeset, the value of TEST_VALUE set in inner is lost when control returns to the outer function. When TEST_VALUE is declared via export, the value set in inner is retained when control returns to outer.
Since there is not a new processes invoked when the outer function calls the inner function, I do not see why export should be used in order for the variable to keep scope in the sub function. Also I have noted that typeset -x behaves the same as typeset whereas I would have expected typeset -x to be equivalent to export.
When I run this program on a machine running ksh88 (AIX, Solaris, HP-UX) or pdksh (Linux) or MKS ksh, typeset, typeset -x, and export behave the same in this example.
For now I have changed typeset to export in order to provide compatibility on ksh93 for the programs using similar code that were developed and tested on ksh88.
Perhaps this is a ksh93 defect?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的脚本调用了
inner
和inner_function
,但后者未定义。这只是问题中的拼写错误还是您的实际脚本也有此错误?您在输出中显示的行为是正确的。
尝试将
outer_typeset_x
的定义从function outer_typeset_x {
更改为outer_typeset_x () {
,您会发现输出是相同的对于outer_export
。Your script has calls to
inner
andinner_function
but the latter is not defined. Is this just a typo in the question or does your actual script have this error also?The behavior you show in your output is correct.
Try changing the definition of
outer_typeset_x
fromfunction outer_typeset_x {
toouter_typeset_x () {
and you'll see that the output will be the same for it as forouter_export
.ksh93 手册对
排版
有这样的说法:关于
导出
:特别是,当您在函数内使用导出时,不会恢复任何内容。
排版似乎旨在提供其他语言中“过程局部变量”提供的功能。我不会称其为设计缺陷。
The ksh93 manual has this to say about
typeset
:And this about
export
:In particular, nothing is restored when you use export inside a function.
It seems likely that
typeset
is intended to provide the functionality provided by "procedure-local variables" in other languages. I wouldn't call that a design defect.