• Linux |奇怪的知识---complete命令---你不知道的命令参数补全---kubectl命令的参数补全


    前言:

    linux下有非常多的命令,其中有一些命令是比较冷门的,但比较有意思,比如,这个complete命令。

    complete命令定义命令或者脚本内的方法的参数自动补全内容是什么(例如,定义某个命令的参数---可以是目录,可以是其它的命令,可以是一个词组,可以是一个脚本内的函数名),这个命令在某些特定的场合是可以提高我们的效率的(请注意关键词,命令和参数)。

    命令补全和命令参数补全是两个不同的概念,这里大家一定要先区分清楚。

    下面就详细介绍一哈此命令。

    一,

    命令的补全:

    例如,任意的一个shell里面输入 com紧接着【tab】,这个是命令补全,只要命令在系统的shell的环境变量里,就可以补全,无需特别设置。

    1. [root@master3 completions]# com
    2. comm command compgen complete compopt

    命令的参数自动补全是什么?

    我想大家应该都知道,命令可带参数也可以不带参数

    例如,ls会打印当前目录下的所有可见内容,此时不需要参数。

    ls -al 会打印当前目录下的所有文件和文件夹并包括它们的详细信息,此时,我们就说 -al是ls这个命令的参数,在准确点说 -al 是ls这个命令的短参数,什么叫短参数什么叫长参数就不在这废话了。这样的参数是传统的unix风格参数。

    那么,还一种参数,例如 kubectl api-resources,这里,我们就会说 api-resources是kubelet的参数,只是这种参数是伯克利实验室最先使用的一种风格(小趣味知识,很早以前看过相关介绍,好像是这么说的)。

    命令的参数自动补全是指的在某一个shell环境下,我们输入一个完整的命令后,空格 【tab】,shell会智能的补全剩下的参数。

    例如,网络管理方面的常用命令ip,当我们安装了自动补全管理命令后:

    首先输入 ip 空格  addr【tab】,在命令下面会返回给我们可能会出现的addr参数开始的所有参数

    1. [root@master1 completions]# ip addr
    2. address addrlabel
    3. [root@master1 completions]# ip addr
    4. address addrlabel

    ip 空格  m【tab】 ,会列出以m开始的这些可用参数 

    1. [root@master1 completions]# ip m
    2. macsec maddress monitor mroute mrule

    OK,命令的参数补全功能需要安装一个管理命令参数的命令,这里有点绕口,请大家仔细理解。

    二,管理命令参数的命令的安装以及kubectl 这个命令的参数补全安装

    在linux下安装命令为:

    OK,如果你有搭建kubernetes集群,那么,可以通过kubectl命令的帮助查询到如何安装命令参数补全:

    k completion --help

    关于安装kubectl命令参数补全的帮助 输出如下:

    1. # Installing bash completion on macOS using homebrew
    2. ## If running Bash 3.2 included with macOS
    3. brew install bash-completion
    4. ## or, if running Bash 4.1+
    5. brew install bash-completion@2
    6. ## If kubectl is installed via homebrew, this should start working immediately
    7. ## If you've installed via other means, you may need add the completion to your completion directory
    8. kubectl completion bash > $(brew --prefix)/etc/bash_completion.d/kubectl
    9. # Installing bash completion on Linux
    10. ## If bash-completion is not installed on Linux, install the 'bash-completion' package
    11. ## via your distribution's package manager.
    12. ## Load the kubectl completion code for bash into the current shell
    13. source <(kubectl completion bash)
    14. ## Write bash completion code to a file and source it from .bash_profile
    15. kubectl completion bash > ~/.kube/completion.bash.inc
    16. printf "
    17. # Kubectl shell completion
    18. source '$HOME/.kube/completion.bash.inc'
    19. " >> $HOME/.bash_profile
    20. source $HOME/.bash_profile

    总结一下,如果是macos系统,安装命令为:

      brew install bash-completion

    如果此macos的bash版本大于4.1,安装命令为:

     brew install bash-completion@2

    如果是linux操作系统,如果是最小化安装,此命令是没有默认安装的,需要搭建一个本地yum仓库或者使用网络yum仓库安装,那么,安装命令为:

    yum -y install bash-completion

    bash-completion安装完成后,需要激活一哈新装的脚本:

    1. source /usr/share/bash-completion/bash_completion
    2. echo "source <(kubectl completion bash)" > ~/.kube/completion.bash.inc
    3. kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
    4. source ~/.kube/completion.bash.inc #当前用户激活kubectl 命令参数补全功能

    如果是需要所有用户都可以使用kubectl 的参数补全:

    1. source /usr/share/bash-completion/bash_completion
    2. echo "source <(kubectl completion bash)" >>/etc/profile
    3. echo "source /usr/share/bash-completion/bash_completion" >>/etc/profile
    4. kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null

    kubectl 命令的参数补全效果:

    kubectl get svc -n 空格【tab】,会列出集群内所有的namespace:

    1. [root@node1 ~]# kubectl get svc -n
    2. default kube-node-lease kube-public kube-system

     OK,那么,如果想要使用别名kubectl呢?

    1. echo "alias k=kubectl">>/etc/profile
    2. echo "complete -F __start_kubectl k">>/etc/profile
    3. source /etc/profile

    测试如下:

    k get pod -n 空格【tab】,将会列出所有namespace

    1. [root@master1 completions]# k get pod -n
    2. default kube-node-lease kube-public kube-system

    k get pod -n kube-s【tab】 【tab】,将会列出kube-system这个命名空间下的所有pod

    1. [root@master1 completions]# k get pod -n kube-system
    2. coredns-7f6cbbb7b8-7c85v kube-apiserver-master2 kube-controller-manager-master2 kube-flannel-ds-b7zf9 kube-proxy-nkgdf kube-proxy-xmrp5 kube-scheduler-master3
    3. coredns-7f6cbbb7b8-h9wtb kube-apiserver-master3 kube-controller-manager-master3 kube-flannel-ds-qcq66 kube-proxy-rb9zk kube-scheduler-master1
    4. kube-apiserver-master1 kube-controller-manager-master1 kube-flannel-ds-5jnr7 kube-flannel-ds-ztdk7 kube-proxy-rvbb7 kube-scheduler-master2

    OK,这些设置将会极大的提高我们管理kubernetes集群的效率,那么,complete -F 这一串是什么情况呢?

    其实根本原因在于kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null 此命令在/etc/bash_completion.d目录下生成了一个名称为kubelet的脚本,此脚本内有一个函数,通过complete -F 指定函数的形式激活了kubectl的别名

    1. __start_kubectl()
    2. {
    3. local cur prev words cword
    4. declare -A flaghash 2>/dev/null || :
    5. declare -A aliashash 2>/dev/null || :
    6. if declare -F _init_completion >/dev/null 2>&1; then
    7. _init_completion -s || return
    8. else
    9. __kubectl_init_completion -n "=" || return
    10. fi
    11. local c=0
    12. local flags=()
    13. local two_word_flags=()
    14. local local_nonpersistent_flags=()
    15. local flags_with_completion=()
    16. local flags_completion=()
    17. local commands=("kubectl")
    18. local must_have_one_flag=()
    19. local must_have_one_noun=()
    20. local has_completion_function
    21. local last_command
    22. local nouns=()

    三,

    complete命令设置参数补全

    首先,我们看一下没有设置complete参数补全的命令是什么情况,以常用的ls命令为例:

    本例中在root家目录下,ls  空格【tab】,此时会自动补全参数的全是当前目录下的文件夹和文件

    1. [root@master1 ~]# pwd
    2. /root
    3. [root@master3 ~]# ls .
    4. ./ ../ .ansible/ .bash_history .bash_logout .bash_profile .bashrc .cshrc .ssh/ .tcshrc .viminfo

    complete -p 命令---查询命令的complete参数补全设置: 

    此时的ls命令我们使用complete -p 看看它有没有设置参数补全(提示ls命令没有设置参数补全,只有默认的参数补全---参数是当前目录下的所有文件夹和文件):

    1. [root@master3 ~]# complete -p ls
    2. -bash: complete: ls: no completion specification

     

    OK,现在使用complete命令更改ls命令参数只补全目录,不补全文件,可以看到设置后,ls命令的参数只补全文件夹了,root目录下就两个文件夹,并且查询complet 也是 -d ls了:

    complete -d 命令---设置命令的参数为 文件夹

    1. [root@master3 ~]# complete -d ls
    2. [root@master3 ~]# ls .
    3. ./ ../ .ansible/ .ssh/
    4. [root@master3 ~]# complete -p ls
    5. complete -d ls

    取消complete对ls的参数补全设置:

    1. [root@master3 ~]# complete -r ls
    2. [root@master3 ~]# complete -p ls
    3. -bash: complete: ls: no completion specification

    complete -c 命令---设置命令的参数为命令

    例如设置ls命令的参数补全为命令:

    ls 空格【tab】,此时ls命令的参数补全是所有命令

    1. [root@master3 ~]# complete -c ls
    2. [root@master3 ~]# ls
    3. Display all 1456 possibilities? (y or n)
    4. : fipscheck _kubectl_drain ntptime ssh-add
    5. ! fipshmac _kubectl_edit numfmt ssh-agent
    6. ./ firewall-cmd _kubectl_exec objcopy ssh-copy-id
    7. [ firewalld _kubectl_explain objdump sshd
    8. 。。。。。略略略

    complete -W "词组" 命令 ---设置命令的参数为词组

    例如,ls命令绑定词组 "start stop" ,ls 空格 【tab】,将会列出词组供选择

    1. [root@master1 ~]# complete -W "start stop" ls
    2. [root@master1 ~]# ls st
    3. start stop

    当然,对于ls命令这样是没有什么意义的,但脚本也可以利用complete绑定词组,这样会使得脚本更加的人性化,智能化:

    例如,nginx.sh 这个脚本,绑定"start stop"作为参数,./nginx.sh 空格【tab】,将会列出词组作为参数供选择

    1. [root@master1 ~]# ls nginx.sh
    2. nginx.sh
    3. [root@master1 ~]# complete -W "start stop " ./nginx.sh
    4. [root@master1 ~]# ./nginx.sh st
    5. start stop



    命令参数补全主要是三个地方的脚本:

    • 第一个是/usr/share/bash-completion/bash_completion,此脚本极为重要,里面的内容比较多,也比较难懂,有兴趣的朋友可以去看看,此脚本是yum安装bash-completion程序后生成的。
    • 第二个是/usr/share/bash-completion/completions/这个目录下的脚本文件,是一些单独命令的参数设置。

    例如look命令的参数设置脚本内容如下 :

    cat /usr/share/bash-completion/completions/look

    1. _look_module()
    2. {
    3. local cur prev OPTS
    4. COMPREPLY=()
    5. cur="${COMP_WORDS[COMP_CWORD]}"
    6. prev="${COMP_WORDS[COMP_CWORD-1]}"
    7. case $prev in
    8. '-t'|'--terminate')
    9. COMPREPLY=( $(compgen -W "char" -- $cur) )
    10. return 0
    11. ;;
    12. '-h'|'--help'|'-V'|'--version')
    13. return 0
    14. ;;
    15. esac
    16. case $cur in
    17. -*)
    18. OPTS="--alternative --alphanum --ignore-case --terminate --version --help"
    19. COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
    20. return 0
    21. ;;
    22. esac
    23. local IFS=$'\n'
    24. compopt -o filenames
    25. COMPREPLY=( $(compgen -f -- $cur) )
    26. return 0
    27. }
    28. complete -F _look_module look

    look --空格【tab】,此时会列出  OPTS="--alternative --alphanum --ignore-case --terminate --version --help" 这些上述脚本定义的参数

    1. root@master1 ~]# look --
    2. --alphanum --alternative --help --ignore-case --terminate --version

     

    • 第三个是/etc/bash_completion.d这个目录下的脚本,kubectl这个命令的参数补全脚本就存放在此,此脚本使用的是关键自定义函数:

    cat /etc/bash_completion.d/kubectl 最后的一段

    1. __start_kubectl()
    2. {
    3. local cur prev words cword
    4. declare -A flaghash 2>/dev/null || :
    5. declare -A aliashash 2>/dev/null || :
    6. if declare -F _init_completion >/dev/null 2>&1; then
    7. _init_completion -s || return
    8. else
    9. __kubectl_init_completion -n "=" || return
    10. fi
    11. local c=0
    12. local flags=()
    13. local two_word_flags=()
    14. local local_nonpersistent_flags=()
    15. local flags_with_completion=()
    16. local flags_completion=()
    17. local commands=("kubectl")
    18. local must_have_one_flag=()
    19. local must_have_one_noun=()
    20. local has_completion_function
    21. local last_command
    22. local nouns=()
    23. __kubectl_handle_word
    24. }
    25. if [[ $(type -t compopt) = "builtin" ]]; then
    26. complete -o default -F __start_kubectl kubectl
    27. else
    28. complete -o default -o nospace -F __start_kubectl kubectl
    29. fi
    30. # ex: ts=4 sw=4 et filetype=sh

    那么,如果我们写的有比较复杂的带有很多参数的脚本,也就可以仿照以上的脚本形式写自定义的参数补全脚本,从而方便我们自己使用脚本或者命令。(目前我还写不出来太复杂的脚本,因此,参数补全脚本也就没机会自己定义了)。

    命令的参数补全意义是比较重大的,通过命令的参数补全功能我们可以快速的上手命令,并对命令的使用加深记忆,这种情况尤其适用于像kubelet这样的参数非常多的命令

    以上就是命令的参数补全基本原理以及一些简单的通过complete命令设定命令的参数补全。

  • 相关阅读:
    混凝土粉末
    蓝桥杯第1390题——A Careful Approach
    大数据分析工具构建智能监测与异常预警
    如何做好shopee的优化—成都扬帆际海教育咨询公司
    使用WildCard充值ChatGPT Plus 会员
    ISIS——基本概念2(域间路由)
    [单片机框架][bsp层][N32G4FR][bsp_adc] ADC配置和使用
    Python&C++相互混合调用编程全面实战-29导入pyffmpeg扩展库完成视频的打开
    消费者偏移量_consumer_offsets相关解析
    VGG16得到的混淆矩阵错误
  • 原文地址:https://blog.csdn.net/alwaysbefine/article/details/127589033