设置一个局部变量,使其值保持在shell函数中的多个调用之间

问题描述 投票:0回答:1

我正在寻找最好的解决方案。我想在函数中使用局部变量,因此忽略在调用函数之前声明的全局变量。

例:

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
1个回答
3
投票

Emulating Static Variables Using Namevars

常规函数范围的局部变量在任何广泛使用的编程语言中对函数的多次调用都不会保留它们的值(如果默认情况下存在此属性,则编写可重入代码将更加困难 - 即,安全的函数递归使用)。在具有这些行为的语言中,具有此行为的变量称为“静态变量”。

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"
}

Original Question: On Local Variables

局部变量在被声明为本地变量之前不是本地变量。您需要将该声明放在函数的顶部:

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的退出状态。

© www.soinside.com 2019 - 2024. All rights reserved.