防止在 bash 中使用 CDPATH 进行路径自动补全?

防止在 bash 中使用 CDPATH 进行路径自动补全?

在我的 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 nospacecd尽管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.

相关内容