2009-12-13 79 views
3

Bash允许您使用TAB键在参数中完成命令名和文件名。 但是,为什么不能共同选择命令?为什么不,甚至更好,一个完成系统,告诉你什么选项呢?Bash完成:我们可以对它做什么,将来会发生什么

听说可编程完成..但不明白的地方它适合..

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

+0

我在使用OSX 10.6的Mac,我使用GNUBash版本3.2.48 – luca 2009-12-13 13:16:45

回答

1

猛砸完成是非常定制,并可以显示选项常用命令。配置文件只需要指定即可。在Debian中,bash完成带有一组配置文件,它们完成不同命令的选项。

例如:

[email protected]:~$ tar 
A c d r t u x 
2

在OS X,你可以通过以下的说明here使用的MacPorts容易安装一组预定义bash完井。查看/opt/local/etc/bash_completion.d中的示例可能会为您提供一些制作其他帮助的方法。

5

如果你想要更完美的表现,请看zsh。它非常像bash,并且从ksh,tcsh等中获得了一些很好的功能。它还修复了一些恼人的bash bug。

它可以做一些非常酷的东西,包括完成远程文件名scp(如果你有基于密钥的身份验证设置)和迷你文档当你完成标签 例如,我很惊喜,当我标签为“罐子“:

[[email protected]:~]% jar <tab> 
0 -- store only without using ZIP compression 
M -- do not create manifest file 
etc... 
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的脚本。

希望有人会发现这个有用的,因为我觉得很难找出。

相关问题