我正在寻找最佳解决方案。我想在函数中使用局部变量,因此忽略在调用函数之前声明的全局变量。
示例:
username="niquit"
User() {
local parsedoptions=$( getopt -q -n "$0" -o u: -- "$@" )
eval set -- "$parsedoptions"
while :
do
case "$1" in
-u)
if [[ $2 ]]
then
local username=$2
fi
shift 2;;
--)
shift
break;;
esac
done
if [[ $username ]]
then
echo "Error"
else
local username="test"
fi
}
User -u test
我当然可以使用更改User_username
函数中的变量名称,或者在函数开始时取消设置所有打结的局部变量,但我想跳过这些解决方案。
答案 0 :(得分:3)
常规函数范围的局部变量在任何广泛使用的编程语言中对函数的多次调用都不会保留它们的值(如果默认情况下存在此属性,则编写可重入代码将更加困难 - 即函数可以安全地递归使用)。在具有这些行为的语言中,具有此行为的变量称为"静态变量"。
Bash本身不支持静态变量。
作为一种解决方法,请考虑一个包含函数名称的全局变量命名约定 - 与namevar结合使用,可以通过所需的更短的本地名称引用这些全局变量:
User() {
declare -g User__username
local -n username=User__username ## NOTE: THIS REQUIRES BASH 4.3 OR NEWER
if [[ $username ]]; then
echo "OK: Already set to $username"
else
username=test
fi
echo "$username"
}
本地变量在声明本地变量之前不是本地变量。您需要将该声明放在函数的顶部:
User() {
local username
if [[ $username ]]; then
echo "FAILED: Non-local variables should never be visible"
else
username="test"
fi
echo "$username"
}
local var=whatever
也是出于其他原因的错误做法:如果您运行var=$(something)
,则退出状态将反映something
是否成功,但如果您运行local var=$(something)
,则它反映了local
是否成功,放弃了something
的退出状态。