当设置nounset时,如何“ - @ - expand(”$ {array [@]}“)在Bash中可能为空数组?

时间:2016-03-29 14:15:34

标签: arrays git bash

我有带set -o nounset选项的bash脚本(我想要那个!)。 现在,我想构造一个命令调用,但我事先并不知道参数的数量,所以我想使用一个数组(下面的例子)。但是,当ARRAY为空数组时,"${ARRAY[@]}"会失败。

问题:@ -expand数组("${ARRAY[@]}")如何在set -o nounset开启时扩展不会失败?

示例:

# Clone git repo. Use --reference if ${reference_local_repo} exist.
reference_local_repo=.....
test -d "${reference_local_repo}" \
    && reference=("--reference" "${reference_local_repo}") \
    || reference=()
git clone "${reference[@]}" http://address/of/the/repo

当然,我可以使用以下代码:

# bad example
reference=''
test -d "${reference_local_repo}" && reference="--reference ${reference_local_repo}"

...但如果本地存储库的路径包含空格,则无效。

作为解决方法,而不是reference=()我使用reference=("-c" "dummy.dummy=dummy")。这样我就避免了空数组,而Bash也没有抱怨。或者,我可以(重命名数组变量和)将“clone”作为第一个数组元素。所以我得到了这个,但我想学习正确的方法。

为了记录,我正在使用GNU bash, version 4.3.42(1)-release (x86_64-pc-linux-gnu)

3 个答案:

答案 0 :(得分:4)

我不明白为什么你在这里使用数组。你可以:

test -d "${reference_local_repo}" \
  && reference="${reference_local_repo}" \
  || reference=""
git clone ${reference:+--reference "$reference"} http://address/of/the/repo

现在没有未定义的变量,并且对于实际上是单个值的数组没有任何误解。

答案 1 :(得分:4)

回答您的具体问题:解决这个问题的原因很简单:

${reference[@]+"${reference[@]}"}

如果未设置引用,则不会扩展任何内容 如果已设置,则会扩展其所有组件。

Read the historical roots for this use

  

大约20年前,如果没有参数,Bourne Shell的一些破坏的小变体将“$ @”替换为空字符串“

当然,在这个具体案例中:

test -d "${reference_local_repo}" && abool="" || unset abool
git clone ${abool+--reference "$reference_local_repo"} http://address/of/the/repo

abool设置为NUL(“”)时(或者如果您选择使用其他值),它会被设置,并且在下一行中它会扩展到加号后面(是的,恰好是两个参数)。

abool未设置时,它会在下一行扩展中完全消失。

也许这更详细:

unset abool
if test -d "${reference_local_repo}"; then abool="ValidDir"; fi
git clone ${abool+--reference "$reference_local_repo"} http://address/of/the/repo

答案 2 :(得分:-1)

您可以使用辅助变量(或只是重新定义相同的变量)来检查数组是否有任何内容:

foo=${your_array[@]:-}

然后:

git clone ... "${foo}" ...

这与nounset标志兼容。如果:-未定义,变量末尾的${your_array[@]:-}扩展($your_array)将产生一个空字符串。