当我在bash:中设置nullglob时
shopt -s nullglob
然后声明一个关联数组:
declare -A arr=( [x]=y )
我无法在数组中取消设置特定密钥:
unset arr[x]
echo ${#arr[@]} # still 1
然而,取消设置nullglob
使此操作如我所期望的那样工作:
shopt -u nullglob
unset arr[x]
echo ${#arr[@]} # now it's 0; x has been removed
这是怎么回事?我不明白shell globbing与这种情况有什么关系。我已经在bash 4.4.19和5.0.0上测试过了。
这可以通过参考bash
文档(man
页面)来解释,转述如下:
分词后,除非设置了
-f
选项,否则Bash会扫描每个单词中的字符'*'
、'?'
和'['
。如果出现其中一个字符,则该单词被视为一个模式,并替换为与该模式匹配的按字母顺序排序的文件名列表。如果找不到匹配的文件名,并且禁用了shell选项
nullglob
,则该单词保持不变。如果设置了nullglob
选项,但未找到匹配项,则会删除该单词
换句话说,nullglob
会影响arr[x]
参数的结果。它要么被单独放置,要么被移除。
使用set -x
:打开执行前回声标志可以看到这种效果
pax$ declare -A arr=( [x]=y )
pax$ shopt -s nullglob
pax$ set -x
pax$ unset arr[x]
+ unset
注意,这是";单词被移除";案例";单词保持不变";案例是这样显示的:
pax$ shopt -u nullglob
+ shopt -u nullglob
pax$ unset arr[x]
+ unset 'arr[x]'
上面最后一个回显的命令还提供了一条线索,说明如果启用了nullglob
,如何删除条目。只需引用防止扩张的论点:
unset 'arr[x]'
无论nullglob
设置如何,这都会起作用,因为文档中有关于引用的部分:
将字符括在单引号中可保留引号中每个字符的文字值。