nullglob禁用了路径名称的标签自动补全。

5

我发现执行shopt -s nullglob会禁用文件和目录的tab补全功能,而执行shopt -u nullglob则可以恢复。为什么目录的tab补全要依赖于nullglob被取消设置呢?

我使用的是Debian 7操作系统上的Bash 4.2.37(1)-release版本。


我在这里没有看到。Bash的版本是什么?发行版是什么?您正在使用哪个命令进行测试? - Etan Reisner
@EtanReisner 各种命令--内置命令如 echo,程序如 ls,别名等等...我认为这并不重要,因为路径的制表符补全不是特定于某个命令的。我已经在问题中添加了我的 Bash 版本和 Linux 发行版。 - Kyle Strand
1
选项卡自动完成实际上是针对特定命令的(有关此内容,请参见complete的输出)。 您可以轻松地为特定命令中断自动完成,而不会影响整体自动完成。 - Etan Reisner
我在我的Debian机器上也看到了这个问题,但在我的CentOS 5机器上没有。 - Etan Reisner
@EtanReisner 通常情况下,制表符自动补全是基于命令的,但我认为用于文件路径的特定补全函数并不是基于命令的,对吗? - Kyle Strand
显示剩余2条评论
1个回答

3

这显然是bash-completion的已知问题,并被列为在3.0版本中需要修复的目标。

但自至少2012年以来,它似乎一直存在。

请参考https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666933

编辑:至少在2011年就已经存在了:http://thread.gmane.org/gmane.comp.shells.bash.completion.devel/3652

我完全不明白nullglob如何导致该电子邮件中列出的问题。

编辑:我现在明白发生了什么。问题在于通配符扩展很愚蠢。它将$2[$j]=\${!ref}\${COMP_WORDS[i]}整个“单词”视为单个通配符并尝试扩展它。通常情况下会失败并保持原样,但对于整个参数使用nullglob会使其消失(从而导致问题)。

快速测试表明,将此内容替换为:

eval $2[$j]=\${!ref}\${COMP_WORDS[i]}

使用以下任一方法:

eval $2\[$j\]=\${!ref}\${COMP_WORDS\[i\]}

或者:

eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"

似乎解决了问题。但我无法保证这两种方法都是完全正确的解决方法。
更新:在debian bash-completion git存储库中已经修复了此问题(以一种我没有想到但显然更好的方式)。 此提交修复了它。还有其他与globbing相关的修复。
从git head获取__reassemble_comp_words_by_ref并在当前文件的顶部进行源控制,似乎可以作为临时解决方法来解决该问题。

1
我同意。更令人失望的是,我看不到任何人讨论问题可能实际上是什么。我很想把第二个链接的报告作为一个SO问题发布出来,看看是否有人能够解释那里发生了什么,因为我不理解。 - Etan Reisner
我见过一些情况(我想是在git完成代码中),它们会出现错误,因为它试图使用glob的默认行为,而没有意识到已经设置了nullglob。nullglob在许多方面都更好,但如果代码在本地设置nullglob并在之后恢复,则使用旧式生成失败通配符的代码也没有问题。这不是正在发生的事情。其结果类似于IFS在类似情况下的使用方式。 - Alex North-Keys
被提示再次查看此问题,我现在明白为什么事情变得混乱了。由于[]括号的存在,shell将完成代码中的$2[$j]=\${!ref}\${COMP_WORDS[i]}行视为glob,并简单地展开整个字符串。如果没有在shell上启用nullglob,则会保持不变(作为失败的扩展)。对我来说,这确实是令人惊讶的行为。在快速手动测试中,转义该行上的两组[](以及循环后面的一组)可以解决问题。将整个参数引用给eval也可以解决问题。 - Etan Reisner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接