设置 nullglob 时关联数组未取消设置
Associative array not unset when nullglob is set
当我在 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
页面)来解释,这里解释为:
After word splitting, unless the -f
option has been set, Bash scans each word for the characters '*'
, '?'
, and '['
. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern.
If no matching filenames are found, and the shell option nullglob
is disabled, the word is left unchanged. If the nullglob
option is set, and no matches are found, the word is removed.
换句话说,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
设置如何,这都有效,因为文档中有关引用的部分:
Enclosing characters in single quotes preserves the literal value of each character within the quotes.
当我在 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
页面)来解释,这里解释为:
After word splitting, unless the
-f
option has been set, Bash scans each word for the characters'*'
,'?'
, and'['
. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern.If no matching filenames are found, and the shell option
nullglob
is disabled, the word is left unchanged. If thenullglob
option is set, and no matches are found, the word is removed.
换句话说,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
设置如何,这都有效,因为文档中有关引用的部分:
Enclosing characters in single quotes preserves the literal value of each character within the quotes.