bash_completion regra para resolver ip em nomes de host

5

Estou tentando criar uma regra bash_completion para meu script rmpxe . Esse script usa <hostname> como seu único argumento. Em seguida, ele resolve esse nome de host em <ip_address> e remove o link simbólico correspondente /srv/tftp/pxelinux.cfg/<ip_address> .

O endereço IP <ip_address> no link simbólico /srv/tftp/pxelinux.cfg/<ip_address> está no formato hexadecimal, mas escrevi um programa simples em C ( getnameinfo ) que resolve esse endereço IP hexadecimal no hostname.

Assim, posso usar meu programa getnameinfo para obter o nome do host do ip hexadecimal:

$ getnameinfo 0A6F010B
server1.mydomain.com

Por exemplo, o comando a seguir excluiria o link simbólico /srv/tftp/pxelinux.cfg/0A6F010B

 $ rmpxe server1.mydomain.com

Agora, para o problema bash_completion : Eu criei o seguinte código que funciona bem, exceto que em vez de completar nomes de hosts (como meu script espera), ele completa endereços IP hexadecimais (isto é, os arquivos de links simbólicos em meu diretório /srv/tftp/pxelinux.cfg/ ). Eu preciso de alguma forma integrar este código, que antes que o argumento seja auto-completado, ele será primeiro resolvido em hostname.

_rmpxe()
{
    local word
    COMPREPLY=()

    if [ 1 -eq "$COMP_CWORD" ]; then
      pushd /srv/tftp/pxelinux.cfg &>/dev/null || return 1
      word="${COMP_WORDS[COMP_CWORD]}"
      COMPREPLY=($(compgen -f "$word"))
      popd &>/dev/null
    fi

}
complete -F _rmpxe rmpxe

Em outras palavras, no momento em que minha conclusão do bash funciona assim:

$ ls /srv/tftp/pxelinux.cfg
0A6F010B 0A6F010C 0A6F010D 0A6F010E

$ rmpxe <tab>
0A6F010B 0A6F010C 0A6F010D 0A6F010E

Considerando que preciso que funcione assim:

$ rmpxe <tab>
server1.mydomain.com server2.mydomain.com server3.mydomain.com
    
por Martin Vegter 15.05.2014 / 18:45

1 resposta

4

Porque você usou compgen -f , significando que compgen listará todos os arquivos e diretórios no caminho atual. No seu caso, isso significa 0A6F010B 0A6F010C 0A6F010D 0A6F010E .

Para obter nomes de host, você pode percorrer o caminho atual, alimentar cada IP para getnameinfo para obter o nome de host correspondente a esse IP, salvá-lo em uma matriz e usar essa matriz como uma lista de palavras com compgen -W . / p>

Eu fiz um teste simples no meu ambiente. Eu criei um arquivo /etc/bash_completion.d/cuonglm :

_rmpxe() {
  local word
  COMPREPLY=()

  if [ 1 -eq "$COMP_CWORD" ]; then
    pushd /home/cuonglm/test &>/dev/null || return 1
    word="${COMP_WORDS[COMP_CWORD]}"
    HOST_ARR=()
    for i in *; do
      HOST_ARR+=($(/home/cuonglm/getnameinfo "$i"))
    done
    COMPREPLY=($(compgen -W "$(printf "%s " "${HOST_ARR[@]}")" -- "$word"))
    popd &>/dev/null
  fi
}
complete -F _rmpxe cuonglm

Eu usei sua função completa com uma pequena modificação:

  • Eu uso uma matriz HOST_ARR para salvar nomes de host.
  • Faz um loop pelo diretório atual (obrigado pushd antes), alimentando cada nome de arquivo para getnameinfo program.
  • Então eu uso o compgen -W para fazer o compgen criar uma lista de palavras para a conclusão.

E aqui está o resultado:

$ cuonglm <Tab>
$ cuonglm server<Tab>
server1.example.com  server2.example.com

Como dois nomes de host têm a mesma parte server , o bash completará automaticamente essa parte primeiro. Se houver outro nome de host, Server.example :

$ cuonglm <Tab>
Server.example server1.example.com  server2.example.com
    
por 17.05.2014 / 20:47

Tags