仅在先前未声明的情况下为 bash 个变量设置默认值

set default values for bash variables only if they were not previously declared

这是我当前的流程:

var[product]=messaging_app
var[component]=sms
var[version]=1.0.7
var[yum_location]=$product/$component/$deliverable_name
var[deliverable_name]=$product-$component-$version

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

  # skip variables that have been previously declared
  if [[ -z ${!default_var} ]] ; then

    # export each index as a variable, setting value to the value for that index in the array
    export "$default_var=${var[$default_var]}"
  fi
done

我正在寻找的核心功能是设置一个默认变量列表,这些默认变量不会覆盖以前声明的变量。

上面的代码做到了这一点,但它也造成了这些变量现在不能相互依赖的问题。这是因为从 "${!var[@]}" 输出的关联数组索引的顺序并不总是与它们声明的顺序相同。

是否存在更简单的解决方案,例如:

declare --nooverwrite this=that

我没能找到类似的东西。

另外,我知道这可以通过 if 语句来完成。然而,使用一堆 if 语句会破坏具有近 100 个默认变量的脚本的可读性。

来自3.5.3 Shell Parameter Expansion

${parameter:=word}

If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.

所以

: ${this:=that}

: 是必需的,否则 shell 会将 ${this:=that} 视为对 运行 的请求,作为命令,无论扩展到什么。

$ echo "$this"
$ : ${this:=that}
$ echo "$this"
that
$ this=foo
$ echo "$this"
foo
$ : ${this:=that}
$ echo "$this"
foo

如果这样更合适的话,您也可以首先使用变量(而不是单独使用)(但要确保清楚,因为在以后的编辑中很容易搞砸)。

$ echo "$this"
$ echo "${this:=that}"
that
$ echo "$this"
that

然而,动态地执行此操作并不容易,可能需要 eval