ksh和bash脚本之间的区别

时间:2014-05-08 22:22:57

标签: bash ksh

考虑以下脚本(用于local_var2的算术语法与此情况无关):

#!/bin/ksh

function my_func1
{
   typeset local_var1=one
   typeset local_var2
   (( local_var2 = 1 ))
   echo my_func1: local_var1 = $local_var1, local_var2 = $local_var2
}

my_func2()
{
   typeset local_var1=two
   typeset local_var2
   (( local_var2 = 2 ))
   echo my_func2: local_var1 = $local_var1, local_var2 = $local_var2
}
local_var1=0
local_var2=0
echo before functions: local_var1 = $local_var1, local_var2 = $local_var2

my_func1
echo after my_func1: local_var1 = $local_var1, local_var2 = $local_var2

my_func2
echo after my_func2: local_var1 = $local_var1, local_var2 = $local_var2

运行时会产生以下输出:

before functions: local_var1 = 0, local_var2 = 0
my_func1: local_var1 = one, local_var2 = 1
after my_func1: local_var1 = 0, local_var2 = 0
my_func2: local_var1 = two, local_var2 = 2
after my_func2: local_var1 = two, local_var2 = 2

(这不是预期的!)

如果我在bash中运行相同的脚本,则输出为:

before functions: local_var1 = 0, local_var2 = 0
my_func1: local_var1 = one, local_var2 = 1
after my_func1: local_var1 = 0, local_var2 = 0
my_func2: local_var1 = two, local_var2 = 2
after my_func2: local_var1 = 0, local_var2 = 0

(这是预期的!)

2 个答案:

答案 0 :(得分:7)

这是ksh93的奇怪之处。

typeset变量将其范围定义为local仅适用于函数定义样式:

function func_name
{
}

不使用函数定义样式:

func_name()
{
}

使用func_name()样式,一切都是全局的。所以ksh的行为正如预期的那样!!!

但在这方面bash明显比ksh更明智。因此,当使用typeset时,它将两个函数中的变量范围设置为本地。

ksh文档中的FAQ条目说明了函数定义之间的区别:

Q18. What is the difference between function name and name()?

A18. In ksh88 these were the same.  However, the POSIX standard
    choose foo() for functions and defined System V Release 2
    semantics to them so that there are no local variables
    and so that traps are not scoped.  ksh93 keeps the ksh88
    semantics for functions defined as function name, and
    has changed the name() semantics to match the POSIX
    semantics.  Clearly, function name is more useful.

答案 1 :(得分:2)

根据this answer中的说明,您最有可能运行ksh的AT& T版本,typeset内置版仅将变量设为本地使用function关键字声明的函数。