意外的 Bash glob 补全即使存在歧义也会使用第一个匹配项

意外的 Bash glob 补全即使存在歧义也会使用第一个匹配项

如果目录中有以下文件:

$ ls
a-file-1
b-file-2
something-else

然后我输入

$ cat *file*<TAB>

该行意外更新为

$ cat a-file-1 |

(管道符表示光标),尽管 glob 也匹配b-file-2。有点奇怪的是,如果我启动另一个 shell,我得到的是 double- 上的匹配列表TAB(我更喜欢这样):

$ cat *file*<TAB><TAB>
a-file-1  b-file-2
$ cat *file*|

问:如何配置此行为?我希望在登录 shell 中有第二种行为。

似乎登录 shell 获得了第一种行为,非登录 shell 获得了第二种行为。但是,我的~/.bash_profile除了启动之外什么也没做~/.bashrc。(我没有.profile。)似乎我必须在某个地方以某种方式更改配置。

不同shopt之处在于只有登录 shell 有extglob onhostcomplete off和,login_shell on但更改这些不会改变上述行为。set -o输出相同。试过了set show-all-if-ambiguous on,但没有效果。我使用的是 Ubuntu 14.04.1。

更新关于@mpy 的评论

在非登录 shell 中,当我在 glob 中包含一个基本目录并按 Alt-G 时,其行为与使用时不同TABTAB。我想在登录 shell 中配置的是后一种特定行为。

Alt- G

$ ls dir/*file*<Alt-G>

更新至

$ ls dir/|

删除 glob 并且不打印任何匹配项。而TABTAB输出匹配项

$ ls dir/*file*<TAB><TAB>
a-file-1  b-file-2
$ ls dir/*file*|

答案1

在 Ubuntu 14.04 中,默认情况下我得到了可怕的首次匹配扩展行为,但我认为这是可编程完成中某些东西的错误。

之后shopt -u progcomp,我得到了良好的列表扩展行为。

您的登录与非登录 shell 行为可能是由于获取.bash_profile/etc/profile或未获取。(或者您的登录 shell 没有获取/etc/bash.bashrc.bashrc,如果您的配置文件未提供它/它们。)

更新:追踪了可编程完成中的错误:打开set -x,并查看了在点击后运行的所有命令的输出TAB。找到了 glob 表达式变成列表的位置,并发现在/usr/share/bash-completion/bash_completion

问题出在这里:(搜索 xspec 找到这些行)

xspec=${1:+"!*.@($1|${1^^})"}
x=$( compgen -f -X "$xspec" -- "$quoted" ) &&

"$quoted"缺少引号,因此在完成处理 shell 函数中它被扩展了。 $quoted在脚本的其他地方用双引号引起来,所以我很确信它应该被引用,这是解决这个问题的正确方法。

报告为https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1387057,希望能尽快得到上游修复并进入所有发行版。

答案2

除了@peter-cordes提到的未加引号的“$quoted”之外,_filedir()函数中还有另一个错误:

--- /usr/share/bash-completion/bash_completion--OLD 2015-08-19 19:58:22.734667377 -0500
+++ /usr/share/bash-completion/bash_completion      2016-01-05 15:56:50.442988910 -0500
@@ -604,6 +604,8 @@
         # 2>/dev/null for direct invocation, e.g. in the _filedir unit test
         compopt -o filenames 2>/dev/null
         COMPREPLY+=( "${toks[@]}" )
+    else
+        compopt -o bashdefault 2>/dev/null
     fi
 } # _filedir()

这可以让你鱼与熊掌兼得:你可以保留你的“shopt -s progcmp”bash_completion如果没有找到匹配项,它将恢复使用 bash 的默认 glob 处理。

相关内容