Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to create a bash_completion rule for my script rmpxe. This script takes <hostname> as its only argument. It then resolves this hostname into <ip_address> and removes the corresponding symlink /srv/tftp/pxelinux.cfg/<ip_address>.

The ip address <ip_address> in the symlink /srv/tftp/pxelinux.cfg/<ip_address> is in hex format, but I have written a simple program in C (getnameinfo) which resolves this hex ip address into hostname.

Thus, I can use my program getnameinfo to get hostname from hex ip:

$ getnameinfo 0A6F010B
server1.mydomain.com

So for example, following command would delete the symlink /srv/tftp/pxelinux.cfg/0A6F010B

 $ rmpxe server1.mydomain.com

Now to my bash_completion problem: I have created following code which works fine, except that instead of completing hostnames (as my script expects) it completes hex IP addresses (i.e. the symlink files in my directory /srv/tftp/pxelinux.cfg/). I need to somehow integrate into this code, that before the argument is autocompleted, it will be first resolved into 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

In other words, at the moment my bash completion works like this:

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

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

whereas, I need it to work like this:

$ rmpxe <tab>
server1.mydomain.com server2.mydomain.com server3.mydomain.com
share|improve this question

1 Answer 1

up vote 5 down vote accepted
+250

Because you use compgen -f, meaning compgen will list all file and directory under current path. In your case, it means 0A6F010B 0A6F010C 0A6F010D 0A6F010E.

To get hostnames, you can loop through your current path, feed each IP to getnameinfo to get hostname correspoding to IP, save it to an array, then use this array as a wordlist with compgen -W.

I do a simple test in my enviroment. I create a file /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

I use your complete function with little modify:

  • I use array HOST_ARRto save hostnames.
  • Loop through current directory (thanks pushd before), feed each filename to getnameinfo program.
  • Then I use compgen -W to make compgen create a wordlist for completion.

And here is result:

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

Because two hostnames have the same portion server, so bash will autocomplete this portion first. If there is another hostname, Server.example:

$ cuonglm <Tab>
Server.example server1.example.com  server2.example.com
share|improve this answer
    
works great. Thanks a lot. –  Martin Vegter May 18 at 14:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.