在bash4之后的版本中,bash支持了一个新功能:自动命令补全。
但是默认该功能是无法实现自动补全的,因为并没有对应的脚本去实现自动补全功能,可以通过安装bash-completion
软件包解决部分命令的自动补全功能。当然也有部分软件是自带bash completion补全脚本的。
但是如果使用我们自己编写的脚本,则就没有这样的功能了,此时,就需要自己编写一个自动补全脚本了。
基本命令介绍
如果想要编写自动补全脚本,首先就需要了解两个命令:complete
和compgen
。
注:这两个都是bash的内置命令。
complete
用于声明指定命令的补全方式
用法:complete [OPTIONS] name [name…]
OPTIONS:
-A:指定补全操作,可以指定使用一下几种操作
- alias:列出所有命令的别名(-a)
- command:列出命令(-c)
- directory:列出当前工作目录下的目录(-d)
- file:列出当前工作目录下的文件(-f)
- service:列出服务名称(-s)
- signal:列出信号
- user:列出用户(-u)
- group:列出组名(-g)
- variable:列出变量(v)
- -W wordlist:指定使用wordlist中的字符串进行补全
- -F funcname:通过指定函数获取字符串列表进行补全
注:获取字符串列表方式并不是通过return,而是通过变量COMPREPLY。
详细用法查询:man complete
compgen
列出匹配的补全字符串
用法:compgen [OPTIONS] word
OPTIONS:
参数与complete相同。
注:如果word关键字开头包含--
,例如--help
,那么就需要在这个关键字前先添加--
,避免与compgen自带的参数混淆。详细用法看下面的脚本。
测试补全脚本
首先自己编写一个脚本,用来充当命令:
# file:~/bin/myscript
#!/usr/bin/bash
# 功能:输出参数
echo $*
方法一:简易补全
首先使用wordlist方式来进行自动补全,直接运行如下命令
complete -W '--help --dir --list-user --list-group' myscript
然后再进行补全测试:
注:该方法只能进行一些简单的关键字进行补全,如果想要补全不同的内容则只能使用方法二
方法二:动态补全
动态补全脚本是通过调用函数的方式来实现的,通过对函数的自定义,可以实现多种多样的功能。
当调用函数时,默认会传递三个变量:
- COMP_WORDS:当前用户命令行输入内容(以数组形式传递)
- CMP_CWORD:当前用户正在补全的字符串数组索引
- COMP_LINE:当前用户命令行内容(字符串形式)
同时,还有三个函数形参:
- $1:需要补全参数的命令名称
- $2:需要补全的参数
- $3:已经补全的参数
还有一个用于返回补全的变量:
- COMPREPLY:返回需要补全的关键字(以数组形式存放)
首先编写一个动态补全脚本
# file:~/test
#!/usr/bin/bash
function _myscript(){
if [[ "${COMP_CWORD}" == "1" ]];then
COMP_WORD="-f -d -cf -cd --current-file --current-directory --file --directory --user --group --help"
COMPREPLY=($(compgen -W "$COMP_WORD" -- ${COMP_WORDS[${COMP_CWORD}]}))
else
case ${COMP_WORDS[$[$COMP_CWORD-1]]} in
-d|--directory)
# 提示/etc/目录下的所有目录
COMP_FILE=$(find /etc/ -maxdepth 1 -type d -print | xargs -n1 basename)
COMPREPLY=($(compgen -W "${COMP_FILE}" ${COMP_WORDS[${COMP_CWORD}]}))
;;
-f|--file)
# 提示/etc/目录下的所有文件
COMP_FILE=$(find /etc/ -maxdepth 1 -type f -print | xargs -n1 basename)
COMPREPLY=($(compgen -W "${COMP_FILE}" ${COMP_WORDS[${COMP_CWORD}]}))
;;
-cf|--current-file)
# 提示当前目录下的文件
COMPREPLY=($(compgen -f ${COMP_WORDS[${COMP_CWORD}]}))
;;
-cd|--current-directory)
# 提示当前目录下的目录
COMPREPLY=($(compgen -d ${COMP_WORDS[${COMP_CWORD}]}))
;;
--user)
# 提示当前系统的所有用户
COMPREPLY=($(compgen -u ${COMP_WORDS[${COMP_CWORD}]}))
;;
--group)
# 提示当前系统的所有组
COMPREPLY=($(compgen -g ${COMP_WORDS[${COMP_CWORD}]}))
;;
esac
fi
}
# 注册命令补全函数
complete -F _myscript myscript
加载该自动补全脚本
source test
测试补全是否可用
自动加载补全脚本
默认补全脚本是不会加载的,首先需要安装bash-completion
软件包,该软件包内有一个脚本用于自动加载补全脚本。
同时需要注意一下安装目录,bash-completion会从三个地方加载自动补全脚本:
- /usr/share/bash-completion/completions/:有软件自行管理的自动补全脚本,最好不要改动
- /etc/bash_completion.d/:该目录下可自行添加所需要的自动补全脚本(全局生效)
- $HOME/.bash_completion:该文件也是自动补全脚本,不过只对当前用户成效,直接将编写的脚本往该文件追加即可。
注:由于这些补全命令都是使用shell语言编写的,所以可以直接添加到/etc/bashrc
或$HOME/.bashrc
文件中也是可以的,并不一定只能安装在上述几个地方中。
参考链接:
本文经「原本」原创认证,作者乾坤盘,访问yuanben.io查询【36TZXLAH】获取授权信息。