之后shopt -s nullglob
,我注意到制表符完成完全停止工作。为什么会这样呢?extglob
显然是良性的, nullglob 还会影响什么?
观察于:
- Ubuntu 14.04(bash
4.3.11(1)-release
) - Arch Linux(bash
4.3.42(1)-release
)
答案1
与 不同的是extglob
,nullglob
shell 行为有很大差异。这意味着包含可能不匹配任何内容的通配符的单词会导致单词消失而不是保留。
在大多数情况下,如果某个目录包含恰好与未加引号的模式匹配的文件,则使用 中断的代码nullglob
也会在没有它的情况下中断。根据模式,此类文件存在的可能性或多或少(并且如果脚本控制存在哪些文件名,则可能是不可能的,例如因为它切换到它填充的临时目录)。
Bash 的 tab 补全默认情况下不受 nullglob 影响,但是如果启用可编程补全就会受到影响,因为一些实现可编程补全的 bash 代码并不健壮。
看看完成打开的参数时会发生什么ls
,set -x
我发现带和不带的输出nullglob
开始有所不同
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=ls
+ line=' '
(工作)对比
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval
+ line=' '
与 nullglob。看到那条eval
线了吗?这表明该参数看起来像一个全局模式。对应的代码在__reassemble_comp_words_by_ref
函数中:
# Append word separator to current or new word
ref="$2[$j]"
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
[
是通配符,通$2[$j]=\${!ref}\${COMP_WORDS[i]}
配符模式也是通配符模式,对于nullglob
,它会被消除,因为它不匹配任何内容。nullglob
如果当前目录包含一个名为 — 的文件,这也将达到平衡,words0=${!ref}${COMP_WORDSi}
这很奇怪,但它可能会发生。
解决方法是添加缺少的双引号:
eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"
该脚本的其他部分可能需要类似的修复,我没有进一步调查。
这是 bash_completion 中的错误(不是 bash 本身)。据报道在2012年并将其固定在路线图对于 3.0 版本。