为Bash脚本实现本地目录范围的自定义自动补全
实现本地目录级脚本补全(无需全局配置)
核心方案
通过在脚本内嵌入补全注册逻辑,结合同名补全选项文件,实现仅在脚本所在目录生效的补全功能,同时支持无执行权限的调用场景。
步骤1:编写脚本主体(以script.sh为例)
将以下代码写入你的脚本,它会自动检测交互式shell环境并注册本地补全规则:
#!/usr/bin/env bash _setup_local_completion() { # 获取脚本绝对路径,确保不同目录同名脚本不冲突 local script_path=$(realpath "${BASH_SOURCE[0]}") local script_dir=$(dirname "$script_path") local script_name=$(basename "$script_path") local comp_file="${script_path%.sh}.autocomplete.txt" # 针对直接调用脚本(./script.sh 或绝对路径)的补全函数 _script_direct_completion() { local cur=${COMP_WORDS[COMP_CWORD]} # 仅在脚本所在目录触发补全 if [[ "$PWD" != "$script_dir" ]]; then COMPREPLY=() return fi # 读取补全文件,忽略注释和空行 local opts=$(grep -v '^#' "$comp_file" 2>/dev/null | grep -v '^$') COMPREPLY=($(compgen -W "$opts" -- "$cur")) } # 针对bash script.sh调用方式的补全函数 _script_bash_invocation_completion() { local cur=${COMP_WORDS[COMP_CWORD]} local prev=${COMP_WORDS[COMP_CWORD-1]} # 仅在脚本所在目录触发补全 if [[ "$PWD" != "$script_dir" ]]; then COMPREPLY=() return fi # 判断前一个参数是否为当前脚本 if [[ "$prev" == "$script_name" || "$prev" == "./$script_name" ]]; then local opts=$(grep -v '^#' "$comp_file" 2>/dev/null | grep -v '^$') COMPREPLY=($(compgen -W "$opts" -- "$cur")) else # 其他情况交给bash默认补全 COMPREPLY=() fi } # 注册补全规则 complete -F _script_direct_completion "$script_path" complete -F _script_direct_completion "./$script_name" complete -F _script_bash_invocation_completion bash } # 仅在交互式shell中执行补全注册(避免非交互式调用时冗余操作) if [[ $- == *i* ]]; then _setup_local_completion fi # -------------------------- # 以下是你的业务逻辑示例 # -------------------------- if [[ $# -eq 0 ]]; then echo "用法:$0 <选项>" echo "可用选项:$(grep -v '^#' "${BASH_SOURCE[0]%.sh}.autocomplete.txt" 2>/dev/null | tr '\n' ' ')" exit 1 fi case "$1" in opt1) echo "执行opt1逻辑" ;; opt2) echo "执行opt2逻辑" ;; opt3) echo "执行opt3逻辑" ;; *) echo "错误:未知选项 $1" ;; esac
步骤2:创建补全选项文件
在同一目录下创建script.autocomplete.txt,写入需要补全的选项(支持注释,以#开头的行会被忽略):
opt1 opt2 opt3 # 这是注释,补全时不会被加载 opt4
步骤3:测试补全功能
- 有执行权限时:在目录下输入
./script.sh op<Tab>,会自动补全为opt1、opt2等选项。 - 无执行权限时:输入
bash script.sh op<Tab>,同样会触发补全。 - 切换目录后:补全规则自动失效,不会影响其他目录的同名脚本。
关键特性说明
- 目录隔离:补全函数会检查当前工作目录是否为脚本所在目录,仅在该目录下生效,彻底避免同名脚本冲突。
- 无需全局配置:所有补全逻辑嵌入脚本内部,不需要修改
/etc/bash_completion.d或~/.bashrc。 - 兼容无权限场景:专门处理
bash script.sh的调用方式,解决Termux等环境中修改权限不便的问题。 - 注释支持:补全文件中可添加注释,便于维护选项列表。
内容的提问来源于stack exchange,提问作者Grifball
相关产品推荐
相关产品推荐

