Is there an explanation of the difference between export and typeset in combination with nested function calls in a KornShell script?
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 oute开发者_StackOverflow社区r_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?
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
.
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.
精彩评论