当我在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
这是怎么回事?我不知道外壳的变化与情况如何相关。我已经在bash 4.4.19和5.0.0上进行了测试。
答案 0 :(得分:3)
这可以通过参考bash
文档(man
页)进行解释,解释如下:
单词拆分后,除非设置了
-f
选项,否则Bash会在每个单词中扫描字符'*'
,'?'
和'['
。如果出现这些字符之一,则将该单词视为一个模式,并替换为与该模式匹配的按字母顺序排序的文件名列表。如果未找到匹配的文件名,并且禁用了外壳程序选项
nullglob
,则该词保持不变。如果设置了nullglob
选项,但没有找到匹配项,则会删除该单词。
换句话说,nullglob
影响您的arr[x]
自变量会发生什么。它将被保留或被删除。
通过使用set -x
打开echo-before-execute标志,您可以看到这种效果:
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
设置如何,该方法均有效:
将字符括在单引号中可保留引号内每个字符的字面值。