击空阵列扩展与`设置-u` [英] Bash empty array expansion with `set -u`

查看:109
本文介绍了击空阵列扩展与`设置-u`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写这已设置-u bash脚本,我有空阵列扩展了一个问题:庆典似乎把一个空数组作为未设置变量扩展期间:

I'm writing a bash script which has set -u, and I have a problem with empty array expansion: bash appears to treat an empty array as an unset variable during expansion:

$ set -u
$ arr=()
$ echo "foo: '${arr[@]}'"
bash: arr[@]: unbound variable

声明-a改编没有帮助的。)

要一个常见的​​解决方案是使用 $ {ARR [@] - } 来代替,从而取代一个空字符串,而不是(未定义)空数组。然而,这不是一个很好的解决方案,因为现在你不能在一个单一的空字符串和一个空阵列的阵列之间辨别。 (@ -expansion是在bash特殊,它扩展了$ {ARR [@]}$ {ARR [0]} $ {ARR [1]}... ,这使得它成为构建命令行的理想工具。)

A common solution to this is to use ${arr[@]-} instead, thus substituting an empty string instead of the ("undefined") empty array. However this is not a good solution, since now you can't discern between an array with a single empty string in it and an empty array. (@-expansion is special in bash, it expands "${arr[@]}" into "${arr[0]}" "${arr[1]}" …, which makes it a perfect tool for building command lines.)

$ countArgs() { echo $#; }
$ countArgs a b c
3
$ countArgs
0
$ countArgs ""
1
$ brr=("")
$ countArgs "${brr[@]}"
1
$ countArgs "${arr[@]-}"
1
$ countArgs "${arr[@]}"
bash: arr[@]: unbound variable
$ set +u
$ countArgs "${arr[@]}"
0

那么,有没有解决这个问题的方法,不是检查数组中的如果(见code下面的示例),或关闭<长等code> -u 设置了一小段?

So is there a way around that problem, other than checking the length of an array in an if (see code sample below), or turning off -u setting for that short piece?

if [ "${#arr[@]}" = 0 ]; then
   veryLongCommandLine
else
   veryLongCommandLine "${arr[@]}"
fi

更新:删除错误标记归因于池上解释

Update: Removed bugs tag due to explanation by ikegami.

推荐答案

首先,它是不是一个错误。

First, it's not a bug.

如果一个下标已被分配一个值数组变量被认为是设置。空字符串是一个有效的值。

An array variable is considered set if a subscript has been assigned a value. The null string is a valid value.

没有标已被分配一个值,所以该数组没有设置。

No subscript has been assigned a value, so the array isn't set.

有一个条件,你可以使用内联来实现你想要的:使用 $ {ARR [@] +$ {ARR [@]}} 而不是$ {ARR [@]}

There is a conditional you can use inline to achieve what you want: Use ${arr[@]+"${arr[@]}"} instead of "${arr[@]}".

$ function args { perl -E'say 0+@ARGV; say "$_: $ARGV[$_]" for 0..$#ARGV' -- "$@" ; }

$ set -u

$ arr=()

$ args "${arr[@]}"
-bash: arr[@]: unbound variable

$ args ${arr[@]+"${arr[@]}"}
0

$ arr=("")

$ args ${arr[@]+"${arr[@]}"}
1
0: 

$ arr=(a b c)

$ args ${arr[@]+"${arr[@]}"}
3
0: a
1: b
2: c

4.2.25和4.3.11

4.2.25 and 4.3.11

这篇关于击空阵列扩展与`设置-u`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆