为什么 nullglob 会影响制表符完成?

mur*_*uru 8 bash autocomplete

之后shopt -s nullglob,我注意到选项卡完成完全停止工作。为什么会这样?extglob显然是良性的,nullglob 还会影响什么?

观察:

  • Ubuntu 14.04 ( bash 4.3.11(1)-release)
  • Arch Linux (bash 4.3.42(1)-release)

Gil*_*il' 9

不像extglobnullglob使得在shell行为的巨大差异。这意味着包含可能不匹配的通配符的单词会导致单词消失而不是保留。

在大多数情况下,nullglob如果某个目录包含恰好与未加引号的模式匹配的文件,则中断的代码在没有它的情况下也会中断。根据模式,此类文件的存在可能或多或少(如果脚本控制存在哪些文件名,则可能是不可能的,例如,因为它切换到它填充的临时目录)。

Bash 的 tab 补全默认不受 nullglob 的影响,但是如果启用可编程补全会受到影响,因为一些实现可编程补全的 bash 代码并不健壮。

看看当完成lswithset -x打开的参数时会发生什么,我看到有和没有的输出nullglob开始不同

+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=ls
+ line=' '
Run Code Online (Sandbox Code Playgroud)

(工作)对比

+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval
+ line=' '
Run Code Online (Sandbox Code Playgroud)

与 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]}
Run Code Online (Sandbox Code Playgroud)

[是通配符,$2[$j]=\${!ref}\${COMP_WORDS[i]}通配符模式也是,使用nullglob,它被消除,因为它不匹配任何东西。nullglob如果当前目录包含一个名为的文件,这也会收支平衡words0=${!ref}${COMP_WORDSi}——这很奇怪,但它可能会发生。

解决方法是添加缺少的双引号:

                eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"
Run Code Online (Sandbox Code Playgroud)

该脚本的其他部分可能需要类似的修复,我没有进一步调查。

这是 bash_completion 中的一个错误(不是 bash 本身)。它在 2012 年被报道并且修复它在3.0 版的路线图上