为什么在函数内部/外部使用typeset时,bash和ksh的结果不同



代码:

#test.sh
test_func(){
var1="$1"
var2="$1"
echo "var1 before typeset: $var1"
echo "var2 before typeset: $var2"
typeset -l var1="$1"
typeset -l var2
echo "var1 after typeset: $var1"
echo "var2 after typeset: $var2"
}
test_func "$1"
var1="$1"
var2="$1"
echo "var1 before typeset: $var1"
echo "var2 before typeset: $var2"
typeset -l var1=$1
typeset -l var2
echo "var1 after typeset: $var1"
echo "var2 after typeset: $var2"

使用bash输出,输入SAMPLE_ININPUT:

var1 before typeset: SAMPLE_INPUT
var2 before typeset: SAMPLE_INPUT
var1 after typeset: sample_input
var2 after typeset: 
var1 before typeset: SAMPLE_INPUT
var2 before typeset: SAMPLE_INPUT
var1 after typeset: sample_input
var2 after typeset: SAMPLE_INPUT

使用ksh:输出

var1 before typeset: SAMPLE_INPUT
var2 before typeset: SAMPLE_INPUT
var1 after typeset: sample_input
var2 after typeset: sample_input
var1 before typeset: sample_input
var2 before typeset: sample_input
var1 after typeset: sample_input
var2 after typeset: sample_input

我不明白为什么bash会在函数中破坏var2,以及为什么当从$1中重新获取值时,ksh更改函数内部的变量会影响函数外部的值。我认为这与他们对局部变量和全局变量的实现有关。

我想要的输出在bash和ksh以及函数内部/外部都是一样的:

var before typeset: SAMPLE_INPUT
var after typeset: sample_input

已用完功能:

var before typeset: SAMPLE_INPUT
var after typeset: sample_input

在bash中,typesetdeclare的别名,除非添加了参数-g,否则在函数内部调用时会使变量成为本地变量。

在ksh中,typeset有不同的行为,这取决于您如何定义函数:使用typeset创建的test_func() { ... }变量是全局的;对于function test_func { ... },它们是本地的。因为您使用的是test_func() {语法,所以在您的ksh代码中,typeset引用预先存在的全局变量,而不是创建局部变量;因此保留了原始值。

如果想要相同的行为,则需要将typeset移到函数之外,或者在shell为bash时添加-g;后者可以通过参数扩展来完成,该参数扩展仅在设置了BASH_VERSION时才发出-g,如下所示:

test_func(){
var="$1"
echo "var before typeset: $var"
typeset ${BASH_VERSION+-g} -l var="$1"
echo "var after typeset: $var"
}
var="SAMPLE_INPUT"
test_func "$var"
echo "var after function: $var"

正确发射:

var after function: sample_input

甚至在狂欢节上。


对于空值,即使在ksh上,如果您更改函数声明语法,使typeset默认创建本地值,也会得到该值:

function test_func {
typeset -l var
var="$1"
}
test_func "SAMPLE_INPUT"
echo "Result is: <$var>"

当在ksh中运行时发出Result is: <>

最新更新