我正在寻找最好的解决方案。我想在函数中使用局部变量,因此忽略在调用函数之前声明的全局变量。
例:
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
函数中的变量名称或在函数开头取消设置所有打结的局部变量,但我想跳过这些解决方案。
常规函数范围的局部变量在任何广泛使用的编程语言中对函数的多次调用都不会保留它们的值(如果默认情况下存在此属性,则编写可重入代码将更加困难 - 即,安全的函数递归使用)。在具有这些行为的语言中,具有此行为的变量称为“静态变量”。
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
的退出状态。