在我的 Mac 上,bash(版本 3.2.53(1))使用文件自动完成命令行参数仅有的在当前目录中。
在工作中的 Linux 计算机上,bash(版本 4.1.2(1))使用当前目录中的文件自动完成命令行参数和父目录。
例如,给定目录树:
/home/pjl/
bin/
foo/
book/
如果在我的 Mac 上我这样做:
$ cd foo
$ cd b<TAB>
$ cd book
bash 自动完成仅有的到book
。然而,当我在 Linux 机器上做同样的事情时:
$ cd foo
$ cd b<TAB>
bin book
$ cd b
bash 提供两种选择:book
从当前目录和 bin
从父目录。
如何让 bash 自动完成仅有的使用当前目录(就像在我的 Mac 上一样)?
在两个都机器,我确实CDPATH
设置为:
.:..:../..:../../..:../../../..:../../../../..:/home/pjl/src:/home/pjl
如果我CDPATH
在 Linux 机器上取消设置,那么 bash 会使用以下命令自动完成仅有的当前目录(这就是我想要的);因此我知道Linux上的bash正在使用CDPATH
.
但我怎样才能保持CDPATH
设定(所以cd
'ing像以前一样工作),但是不是CDPATH
进行自动补全时使用 bash 吗?
另一种可接受的行为是自动完成青睐当前目录和使用CDPATH
当且仅当当前目录中没有任何内容匹配。
答案1
~/.bashrc
正确的方法是在上面建议的 @Gilles中使用以下内容(此处较短的版本):
_my_cd () { CDPATH= _cd "$@";}
更好的方法是检查CDPATH
当且仅当在本地找不到匹配项时:
_my_cd () { CDPATH= _cd "$@"; if [ -z "$COMPREPLY" ]; then _cd "$@"; fi;}
通过这种方式,您可以获得可编程完成的功能,而不会造成麻烦。不要忘记
complete -F _my_cd cd
/usr/share/bash-completion/bash_completion
由于某种原因-o nospace
(cd
尽管nospace
似乎是默认的),所以你不妨:
complete -F _my_cd -o nospace cd
答案2
罪魁祸首就是你bash_完成,根本不是你的 bash 版本。
和bash_completion 存储库中的 head 版本,cd
自动完成包括 下的目录CDPATH
。
您可以直接对本地进行更改bash_completion
,但最好编写自己的cd
自动完成功能。
如果您想要全局效果,请创建一个包含/etc/bash_completion.d/cd
以下内容的文件:
_cd()
{
local cur=${COMP_WORDS[COMP_CWORD]}
_init_completion || return
local IFS=$'\n' i
compopt -o filenames
local -r mark_dirs=$(_rl_enabled mark-directories && echo y)
local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y)
_filedir -d
if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
i=${COMPREPLY[0]}
if [[ "$i" == "$cur" && $i != "*/" ]]; then
COMPREPLY[0]="${i}/"
fi
fi
return 0
}
if shopt -q cdable_vars; then
complete -v -F _cd -o nospace cd
else
complete -F _cd -o nospace cd
fi
此版本除部分内容外,全部来自原版CDPATH
。
如果您只想用于您的设置,您可以.bashrc
使用以下内容进行编辑:
_my_cd () {
declare CDPATH=
_cd "$@"
}
complete -F _my_cd cd
CDPATH
在某些情况下,bash 补全功能在您的 Mac OSX 中不起作用,您的bash_completion
系统太旧或者您尚未加载它。
您可以使用BASH_COMPLETION_COMPAT_DIR
变量来设置加载自定义完成函数的位置bash_completion
,默认为/etc/bash_completion.d
.