【问题标题】:How to auto-complete a multi-level command aliased to a single command?如何自动完成别名为单个命令的多级命令?
【发布时间】:2023-03-06 14:22:01
【问题描述】:

假设我有两个 bash 函数:

dock() { sudo docker $@ ;}

dock-ip() { sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}

如何使用 第二个函数 让 bash 自动完成?

使用第一个,就像添加一样简单:

_completion_loader docker; complete -F _docker dock

这不适用于第二个。 Docker 的自动完成源代码位于 Debian Stretch 上的 /usr/share/bash-completion/completions/docker。我有更多函数,如dock-rundock-exec 等,所以我不想为每个函数编写自定义完成函数。

另外,complete -F _docker_container_inspect dock-ip 仅部分有效; tab 只列出容器,不完成部分字符串。


研究:

How do I autocomplete nested, multi-level subcommands?

https://superuser.com/questions/436314/how-can-i-get-bash-to-perform-tab-completion-for-my-aliases

【问题讨论】:

    标签: bash docker autocomplete alias


    【解决方案1】:

    凭借一小时的 bash 完成经验,我拆开了 docker 完成脚本 (/usr/share/bash-completion/completions/docker) 和 bash_completion.sh 脚本以提出一个包装函数:

    # Usage:
    #   docker_alias_completion_wrapper <completion function> <alias/function name>
    #
    # Example:
    #   dock-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
    #   docker_alias_completion_wrapper __docker_complete_containers_running dock-ip
    function docker_alias_completion_wrapper {
      local completion_function="$1";
      local alias_name="$2";
    
      local func=$(cat <<EOT
        # Generate a new completion function name
        function _$alias_name() {
            # Start off like _docker()
            local previous_extglob_setting=\$(shopt -p extglob);
            shopt -s extglob;
    
            # Populate \$cur, \$prev, \$words, \$cword
            _get_comp_words_by_ref -n : cur prev words cword;
    
            # Declare and execute
            declare -F $completion_function >/dev/null && $completion_function;
    
            eval "\$previous_extglob_setting";
            return 0;
        };
    EOT
      );
      eval "$func";
    
      # Register the alias completion function
      complete -F _$alias_name $alias_name
    }
    export -f docker_alias_completion_wrapper
    

    然后我创建了这样的别名/函数:

    # Get container IP
    dock-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
    docker_alias_completion_wrapper __docker_complete_containers_running dock-ip
    
    # Execute interactive container
    dock-exec()  { docker exec -i -t --privileged $@ ;}
    docker_alias_completion_wrapper __docker_complete_containers_all dock-exec
    
    ... 
    

    请务必在您的配置文件别名脚本顶部调用 _completion_loader docker; 以加载主要的 Docker 完成脚本。我邀请更多熟练的 bash 程序员来改进这个答案。

    【讨论】:

    • 很好,将_completion_loader docker; 行添加到您的第一个示例代码中,供更多懒惰的人使用:P
    猜你喜欢
    • 2023-04-05
    • 2021-05-27
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多