是否有解释导出和排版与 KornShell 脚本中的嵌套函数调用相结合的区别?

发布于 2024-09-04 10:33:09 字数 2316 浏览 9 评论 0原文

我遇到了 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甲如呢乙后呢 2024-09-11 10:33:09

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

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

尝试将 outer_typeset_x 的定义从 function outer_typeset_x { 更改为 outer_typeset_x () {,您会发现输出是相同的对于outer_export

Your script has calls to inner and inner_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 from function outer_typeset_x { to outer_typeset_x () { and you'll see that the output will be the same for it as for outer_export.

ˉ厌 2024-09-11 10:33:09

ksh93 手册对排版有这样的说法:

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

关于导出

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

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

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

The ksh93 manual has this to say about typeset:

When invoked inside a function defined with the function name syntax, a new instance of the variable vname is created, and the variable's value and type are restored when the function completes.

And this about export:

the given names are marked for automatic export to the environment of subsequently-executed commands.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文