You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为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:测试补全功能

  1. 有执行权限时:在目录下输入./script.sh op<Tab>,会自动补全为opt1、opt2等选项。
  2. 无执行权限时:输入bash script.sh op<Tab>,同样会触发补全。
  3. 切换目录后:补全规则自动失效,不会影响其他目录的同名脚本。

关键特性说明

  • 目录隔离:补全函数会检查当前工作目录是否为脚本所在目录,仅在该目录下生效,彻底避免同名脚本冲突。
  • 无需全局配置:所有补全逻辑嵌入脚本内部,不需要修改/etc/bash_completion.d或~/.bashrc。
  • 兼容无权限场景:专门处理bash script.sh的调用方式,解决Termux等环境中修改权限不便的问题。
  • 注释支持:补全文件中可添加注释,便于维护选项列表。

内容的提问来源于stack exchange,提问作者Grifball

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:46:33