如果目录中有以下文件:
$ 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 on
、hostcomplete 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 处理。