【bash自动补全原理】

1 bash自动补全原理

1)自动补全依赖于bash的内置命令completecompgen、和/etc/bash_completioin.d路径下的自动补全脚本。补齐功能可以通过脚本指定命令参数如何补齐。默认补全脚本在/etc/bash_completion.d目录下。

2)一般系统中会安装bash-completion包来更好的进行补全效果。不同版本安装位置不同,原理类似。一般会有个bash-completion的脚本,这个脚本会在bash初始化的时候加载,获取脚本的位置可以通过/etc/profile.d/bash_completion.sh文件查看,补全功能的配置也是通过这个脚本导入的。内容如下:

bash 复制代码
1 # shellcheck shell=sh disable=SC1091,SC2039,SC2166
2 # Check for interactive bash and that we haven't already been sourced.
3 if [ "x${BASH_VERSION-}" != x -a "x${PS1-}" != x -a "x${BASH_COMPLETION_VERSINFO-}" = x ]; then
4    # Check for recent enough version of bash.
5    if [ "${BASH_VERSINFO[0]}" -gt 4 ] ||
6        [ "${BASH_VERSINFO[0]}" -eq 4 -a "${BASH_VERSINFO[1]}" -ge 2 ]; then
7        [ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] &&
8            . "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
9        if shopt -q progcomp && [ -r /usr/share/bash-completion/bash_completion ]; then
10            # Source completion code.
11            . /usr/share/bash-completion/bash_completion
12        fi
13    fi

14 fi

详解

(1)第3行:检查三个条件是否同时满足

复制代码
* `BASH_VERSION` 是否被设置(即是否在 Bash 环境中)。  
* `PS1` 是否被设置(`PS1` 是 Bash 的主提示符变量,如果它被设置,那么说明 Bash 正在交互式模式下运行)。 
* `BASH_COMPLETION_VERSINFO` 是否未被设置(如果它未被设置,那么可能还没有加载 bash completion)。这三个条件都满足时,脚本才会继续执行。

(2)第5、6 行

复制代码
这行代码检查 Bash 的版本是否大于 4.0 或者等于 4.2 或更高版本。这是为了确保 Bash 的版本足够新,能够支持 bash completion。

(3)第7、8行

复制代码
这行代码检查 ${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion 文件是否存在且可读,如果是,则尝试加载这个文件。这里 ${XDG_CONFIG_HOME:-$HOME/.config} 是一个参数扩展,它的意思是如果 XDG_CONFIG_HOME 环境变量被设置,那么使用它的值,否则使用 $HOME/.config。

(4)第9行

复制代码
这行代码首先使用 shopt -q progcomp 检查 bash completion 是否已经启用。如果已经启用,并且 /usr/share/bash-completion/bash_completion 文件存在且可读,那么加载这个文件,以启用更丰富的 bash completion 功能。

(5)第11行

复制代码
执行脚本/usr/share/bash-completion/bash_completion,该脚本中有更丰富的bash complete功能。

bash_completion脚本会加载/etc/bash_completion.d目录下自动补全脚本

bash 复制代码
# source compat completion directory definitions
compat_dir=${BASH_COMPLETION_COMPAT_DIR:-/etc/bash_completion.d}
if [[ -d $compat_dir && -r $compat_dir && -x $compat_dir ]]; then
    for i in "$compat_dir"/*; do
        [[ ${i##*/} != @($_backup_glob|Makefile*|$_blacklist_glob) && -f \
        $i && -r $i ]] && . "$i"
    done
fi
unset compat_dir i _blacklist_glob

# source user completion file
user_completion=${BASH_COMPLETION_USER_FILE:-~/.bash_completion}
[[ ${BASH_SOURCE[0]} != "$user_completion" && -r $user_completion && -f $user_completion ]] &&
    . $user_completion
unset user_completion

unset -f have
unset have

set $BASH_COMPLETION_ORIGINAL_V_VALUE
unset BASH_COMPLETION_ORIGINAL_V_VALUE

# ex: filetype=sh
相关推荐
归叶再无青6 天前
web服务安装部署、性能升级等(Apache、Nginx)
运维·前端·nginx·云原生·apache·bash
归叶再无青6 天前
企业级web服务(Tomcat开源web应用服务器)
运维·前端·开源·tomcat·bash
chao_7897 天前
构建start_app.sh,实现快速启动项目
python·bash·终端·前后端
笨笨D幸福8 天前
应用程序重定向技术(Shim)
bash·scoop·shim
xuchaoxin13758 天前
bash@bash帮助命令help@bash命令可用选项设置@bash -c@set命令@set --
bash
ol木子李lo9 天前
Linux 命令备忘录
linux·运维·服务器·windows·编辑器·ssh·bash
dingdingfish10 天前
Bash学习 - 第10章:Installing Bash
bash·make·shell·install·configure·5.3
dingdingfish11 天前
Bash学习 - 第8章:Command Line Editing,第3节:Readline Init File
bash·init·bind·readline
dingdingfish11 天前
Bash学习 - 第8章:Command Line Editing,第6-8节:Programmable Completion
bash·shell·completion·complete·compgen·compopt
dingdingfish12 天前
Bash学习 - 第8章:Command Line Editing,第4-5节:Bindable Readline Commands
bash·emacs·vi·bind·readline