我们目前的设置是在一个配置文件中声明几个变量,然后运行一些依赖于这些变量的进程。我试图提供的其他功能是一个默认的_variables脚本,该脚本将为配置文件中的所有变量提供默认值,同时不重写配置文件中声明的任何内容。
这是我当前的代码:

#!/bin/bash -x

# allows var to be used as an associative array
declare -A var

# variable declarations must be of the form:
# var[var_name]=var_value
# after processing loop, the above will be evaluated as:
# export var_name=var_value

# declare default variables
var[a]=a_val
var[b]=b_val
var[c]=c_val
var[d]=d_val

# iterate on associative array indices
for default_var in `echo "${!var[@]}"`
do

test_var=\$${default_var}

  # only export variables that have not been previously declared
  if [[ -z `eval $test_var` ]]
  then

    # export each index name as a variable
    export $default_var=${var[$default_var]}
  fi
done

我当前得到的错误是eval语句试图执行在脚本运行之前声明的变量的值。例如,如果上面的脚本运行了两次,则错误为:
-sh: a_val: command not found
-sh: b_val: command not found
-sh: c_val: command not found
-sh: d_val: command not found

现在我肯定想用一种更优雅的方法来解决这个问题,但这是我能想到的最好的办法。最后,我知道正常导出值并分别检查每个变量是否被分配是一种更“正确”的方法,但我不想让脚本呈指数膨胀,我也不想让人们每次向脚本中添加新变量时都必须复制逻辑,而且我不能在配置文件允许它覆盖默认值之前运行default_variables脚本,因为某些默认值依赖于配置值。
提前感谢您的帮助!

最佳答案

不要使用eval,这会导致其参数作为命令执行。您所需要的只是由$default_var命名的变量的值。间接变量引用有一个非常好的语法:

if [[ -z ${!default_var} ]]

尽管你真的想测试非空的。-z空的测试。应该是这样。
if [[ -n ${!default_var} ]]

此外,这一点过于复杂,而且可以说是不正确的:
for default_var in `echo "${!var[@]}"`

写下:
for default_var in "${!var[@]}"

10-06 04:50
查看更多