我们目前的设置是在一个配置文件中声明几个变量,然后运行一些依赖于这些变量的进程。我试图提供的其他功能是一个默认的_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[@]}"