Bash变量变量通过函数传递

时间:2015-09-23 21:25:45

标签: bash shell

我在这里查看了其他几个变量变量帖,但似乎仍然坚持我想要尝试的东西。

我有一个现有的脚本,它有一系列类似的块,如

set_name="something"

# Required values
var1=$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "key1_${set_name}")
if [[ -z "$var1" ]]; then
    echo "Cannot find required var1"
    exit 1
fi
var2=$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "key2_${set_name}")
if [[ -z "$var2" ]]; then
    echo "Cannot find required var2"
    exit 1
fi
# Optional, okay to be empty
var3=$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "key3_${set_name}")
var4=$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "key4_${set_name}")

我试图将一些样板检查考虑在内以使这组查找分配更容易阅读(我认为无论如何)。我尝试的最后一次迭代(显然不起作用)看起来像

ZTest () {
    var=$1
    if [[ -z "${!var}" ]]; then
        echo $2
        exit 1
    fi
}

VarRequire () {
    var=$1
    key=$2
    errmsg=$3
    VarLookup ${!var} $key
    ZTest ${!var} $errmsg
}

VarLookup () {
    var=$1
    key=$2
    ${!var}=$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "$key")
}

# Required 
VarRequire "var1" "key1_${set_name}" "Cannot find required var1"
VarRequire "var2" "key2_${set_name}" "Cannot find required var2"

# optional 
VarLookup "var3" "key3_${set_name}"
VarLookup "var4" "key4_${set_name}"

最终结果是我能够在脚本中引用$ var1,$ var2,$ var3,$ var4,与原始行相同。

我在bash中尝试的是什么?

4 个答案:

答案 0 :(得分:2)

Var *函数中的间接过多

VarRequire () {
    local var=$1
    local key=$2
    local errmsg=$3
    VarLookup "$var" "$key"
    ZTest "$var" "$errmsg"
}

VarLookup () {
    local var=$1
    local key=$2
    declare -g "$var"="$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "$key")"
}

declare命令允许您使用变量的值作为变量名称。我使用-g选项,因此变量是全局的。

ZTest函数确实需要间接。

答案 1 :(得分:2)

ZTest已作为参数扩展运算符提供:

: ${var1:?Cannot find required var1}

尽管如此,你与VarLookup关系密切;您需要使用declare命令来创建变量。 ${!var}仅用于在变量存在时访问该值。 (请注意,declare需要-g选项以避免创建局部变量,并且该选项仅在4.2版中引入。)

VarLookup () {
  local var=$1
  local key=$2
  declare -g "${var}=$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "$key")"
}

在4.2版之前,您可以使用printf代替declare

printf -v "$var" '%s' "$(REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "$key")"

我会抵制在shell中重构太多的冲动,因为间接可能很脆弱。我建议更直接的东西,如

var_lookup () {
    REQUIRED_ENV_VAR=/path/to/somewhere mybinary -p "${1}_$set_name"
}

var1=$(var_lookup key1); : ${var1:?Cannot find required var1}
var2=$(var_lookup key2); : ${var2:?Cannot find required var2}
var3=$(var_lookup key3)
var4=$(var_lookup key4)

答案 2 :(得分:0)

来自BASH联机帮助页

   local [option] [name[=value] ...]
          For  each  argument,  a local variable named name is created,
          and assigned value.  The option can be any of the options
          accepted by declare.  When local is used within a function, it
          causes the variable name to have a visible scope restricted to 
          that function and its children.  With no operands, local writes a
          list of local variables  to the  standard  output.   It is an
          error to use local when not within a function.  The return status
          is 0 unless local is used outside a function, an invalid name is
          supplied, or name is a readonly variable.

所以答案是肯定的。如果在函数中声明变量local,并且它调用另一个函数,那么该函数也可以访问该变量。

答案 3 :(得分:0)

您可以在开始时设置REQUIRED_ENV_VAR=/path/to/somewhere一次吗? 当找到var时,你的mybinary会返回0吗?

您可能喜欢

之类的内容
function mylog {
   errortype=$1
   shift
   echo "(maybe show ${errortype}) $*"
   if [ "$errortype" = "error" ]; then
      exit 1
   fi
}

var1=$(mybinary -p "key1_${set_name}") || mylog error "Cannot find required var1"
var2=$(mybinary -p "key2_${set_name}") || mylog error "Cannot find required var2"
var3=$(mybinary -p "key3_${set_name}") 
var4=$(mybinary -p "key4_${set_name}") || mylog debug "Just want to say something"