Wednesday, August 28, 2019

Autocomplete in bash



https://www.tldp.org/LDP/abs/html/tabexpansion.html
 and compgen builtins make it possible for tab completion to recognize partial parameters and options to commands. In a very simple case, we can use complete from the command-line to specify a short list of acceptable parameters.
bash$ touch sample_command
bash$ touch file1.txt file2.txt file2.doc file30.txt file4.zzz
bash$ chmod +x sample_command
bash$ complete -f -X '!*.txt' sample_command


bash$ ./sample[Tab][Tab]
sample_command
file1.txt   file2.txt   file30.txt
  
The -f option to complete specifies filenames, and -X the filter pattern.
For anything more complex, we could write a script that specifies a list of acceptable command-line parameters. The compgen builtin expands a list of arguments to generate completion matches.
Let us take a modified version of the UseGetOpt.sh script as an example command. This script accepts a number of command-line parameters, preceded by either a single or double dash. And here is the corresponding completion script, by convention given a filename corresponding to its associated command.
Example J-1. Completion script for UseGetOpt.sh
# file: UseGetOpt-2
# UseGetOpt-2.sh parameter-completion

_UseGetOpt-2 ()   #  By convention, the function name
{                 #+ starts with an underscore.
  local cur
  # Pointer to current completion word.
  # By convention, it's named "cur" but this isn't strictly necessary.

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
                               --file --log --test --help --' -- $cur ) );;
#   Generate the completion matches and load them into $COMPREPLY array.
#   xx) May add more cases here.
#   yy)
#   zz)
  esac

  return 0
}

complete -F _UseGetOpt-2 -o filenames ./UseGetOpt-2.sh
#        ^^ ^^^^^^^^^^^^  Invokes the function _UseGetOpt-2.
https://stuff-things.net/2016/05/11/bash-autocompletion/
The command that setups autocompletion is complete. When giving it a list, pass them in as an augument to the -Woption:
1
complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" wait-for-host
I’m capturing the output of the command with $() and wrapping it in double quotes. The last argument is the name of the command (which can be also be a function or alias) that will use this autocompletion. Now we get this:
1
2
3
~ wait-for-host www<TAB>
www.example.com            www1.example.com
~ wait-for-host www
That works fine, but it’s static and applies only to one command. Instead you can create a reusable function.
1
2
3
4
5
6
7
8
9
_known_hosts() {
    local know_hosts cur
    known_hosts=$(cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\[")

    cur="${COMP_WORDS[COMP_CWORD]}"

    COMPREPLY=( $(compgen -W "$known_hosts" -- ${cur}) )
    return 0
}
BASH auto completion functions are powerful things, but for today we’re keeping it simple. First we build a list of options as before and store it in $known_hosts. Second we get the current word, the command argument, which is be tab completed. Finally, we pass that list and that word into compgen which is BASH’s internal matcher. compgen has some powerful features, but in this case it’s just going to return a list of hosts in $known_hosts that start with the word we hit tab on.
Then we tell the completion that we are using a function by giving it the -f option, along with the function name, instead of -W:
1
complete -F _known_hosts wait-for-host
And you can use the _known_hosts function for other commands as well:
1
complete -F _known_hosts ssh
This is a good exercise in understanding autocompletion, but it’s pretty basic. Fortunately, people have already done all of the hard work in the bash-completion project. This ships by default with many Linux distros. On the Mac:
1
brew install bash-completion
The add:
1
2
3
if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi
https://sanctum.geek.nz/arabesque/bash-hostname-completion/
For example, given the following hosts(5) file in place at /etc/hosts:
127.0.0.1      localhost
192.0.2.1      web.example.com www
198.51.100.10  mail.example.com mx
203.0.113.52   radius.example.com rad
An appropriate call to compgen would yield this output:
$ compgen -A hostname

We could then use this to complete hostnames for network diagnostic tools like ping(8):
$ complete -A hostname ping
There’s a simple way to make host completion much more useful by defining the HOSTFILE variable in ~/.bashrc to point to any other file containing a list of hostnames. You could, for example, create a simple file ~/.hosts in your home directory, and then include this in your ~/.bashrc:
# Use a private mock hosts(5) file for completion
HOSTFILE=$HOME/.hosts
This setup allows you to set hostname completion as the default method for all sorts of network-poking tools, falling back on the usual filename completion if nothing matches with -o default:
$ complete -A hostname -o default curl dig host netcat ping telnet

https://iridakos.com/tutorials/2018/03/01/bash-programmable-completion-tutorial.html

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts