3

Bash 允许您使用 TAB 键完成参数中的命令名称和文件名称。但是为什么不是命令的常用选项呢?为什么不提供一个更好的完成系统来告诉您选项的作用呢?

我听说可编程完成..但不明白它适合..

所以我的问题是:有没有办法实现我的要求?与 Bash 结合的其他工具可能......或者什么?

4

7 回答 7

5

如果您想要更出色的完成,请查看zsh。它与 bash 非常相似,并从 ksh、tcsh 等中汲取了一些好的特性。它还修复了一些恼人的 bash 错误。

它可以做一些非常酷的事情,包括完成 scp 的远程文件名(如果您设置了基于密钥的身份验证)和完成选项卡时的迷你文档 例如,当我前几天在“jar”上添加选项卡时,我感到很惊喜:

[steven@sexy:~]% jar <tab>
0  -- store only without using ZIP compression
M  -- do not create manifest file
etc...
于 2009-12-13T18:31:23.107 回答
2

在 OS X 上,您可以按照此处bash的说明使用 MacPorts轻松安装一组预定义的补全。查看示例中的示例可能会给您一些制作其他示例的想法。/opt/local/etc/bash_completion.d

于 2009-12-13T18:27:13.060 回答
2

这是 bash 的官方手册页:Bash 参考手册:可编程完成

于 2009-12-13T13:45:49.893 回答
1

这是 bash 的一个标准特性:可编程完成

于 2009-12-13T13:14:17.513 回答
1

Bash 支持参数完成: http: //www.debian-administration.org/articles/316

于 2009-12-13T13:15:10.243 回答
1

Bash 补全是非常可定制的,并且可以显示常用命令的选项。配置文件只需要这样指定。在 Debian 中,bash 补全带有一组用于完成不同命令选项的配置文件。

例如:

alanhaggai@neon:~$ tar
A  c  d  r  t  u  x
于 2009-12-13T13:15:19.323 回答
0

我不喜欢这里的任何答案,并想提供几个具体的例子。

有时我有许多具有公共前缀的目录,并且希望能够通过键入目录名称的唯一部分(位于目录名称的中间或末尾)来完成它们。

我能够编写一个完成函数来完成此任务:

_cd(){
    # Backup old nullglob setting
    local shoptbakup="`shopt -p nullglob`"
    shopt -s nullglob

    local cur opts i opt
    local IFS=$'\n'
    cur="${COMP_WORDS[COMP_CWORD]}"

    # Home directory substitution
    if [[ "${cur:0:1}" == '~' ]]; then
        cur="$HOME/${cur:1}"
    fi

    if [[ $cur == */* ]]; then
        opts=(${cur}*/)
    else
        opts=(*${cur}*/)
    fi

    # Prevent trailing//
    i=0
    for opt in "${opts[@]}"; do
        #opts[$i]=${opt%${opt##*[!/]}}
        opts[$i]=${opt%/}
        i=$((i+1))
    done

    # Restore nullglob setting
    eval "$shoptbakup" 2>/dev/null

    COMPREPLY=("${opts[@]}")
}
complete -o filenames -o bashdefault -o nospace -F _cd cd

所以现在根据我的提示,我可以这样做:

$ ls
test 6/  test 7/  test 8/  test1/  test2/  test3/  test4/  test5/
$ cd 7[TAB]

它会自动完成:

$ cd test\ 7/

您可能想要使用可编程完成的另一个原因是您编写脚本并希望能够为您列出或完成选项。这个页面有一些非常好的例子:

http://fahdshariff.blogspot.com/2011/04/writing-your-own-bash-completion.html

这是一个例子:

假设我有一个名为 listanimals 的脚本。我可以编写一个完成函数来帮助填写选项

# complete sendevent
_listanimals()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    local prev=${COMP_WORDS[COMP_CWORD-1]}

    if [[ $prev == "--sort-direction" ]]; then
        COMPREPLY=( $( compgen -W "horizontal vertical" -- $cur ) )
        return 0
    elif [[ $prev == "--type" ]];then
        COMPREPLY=( $( compgen -W "mammals reptiles birds fish marsupials insects misc" -- $cur ) )
        return 0
    elif [[ $prev == "--size" ]]; then
        COMPREPLY=( $( compgen -W "tiny small medium large huge" -- $cur ) )
        return 0
    fi


    # completing an option
    if [[ "$cur" == --* ]] || [[ $cur == "" ]]; then
        COMPREPLY=( $( compgen -W "--sort-direction --type --size" -- $cur ) )
    fi
}
complete -F _listanimals listanimals

现在我可以这样做了:

$ listanimals --[TAB][TAB]
--size            --sort-direction  --type
$ listanimals --t[TAB]

这将自动填写:

$ listanimals --type

然后我可以这样做:

$ listanimals --type [TAB][TAB]
birds       fish        insects     mammals     marsupials  misc        reptiles

我相信你可以弄清楚其余的。这是一个工作示例,因此如果您想尝试一下,只需将其复制/粘贴到文件中(例如 sample.sh)并在 bash中获取它source sample.sh。您实际上并不需要一个名为 listanimals 的脚本。

希望有人会发现这很有用,因为我发现很难弄清楚。

于 2014-05-07T23:25:50.950 回答