Bash auto completion on your workstation

Simplify

I really like to keep things simple but on the other hand I need to know how things work on the inside.
in most cases clicking double TAB ( <tab><tab>) can save us between a few seconds of writing to a complete hours finding out the next argument, And it really fun to use it.

Most of the commands that we are using to interact with OpenShift have a build-in completion code for both bash and zsh so Red Hat actually made our lives much more simple but in some cases we don’t have an auto completion and here is where custom bash completion comes along.

Install

In order to use bash completion first we need to make sure it is installed on our system :

# dnf install -y bash-completion

Now we can move on and see how to utilize it.

Generate

We will start with a very simple example of Bash auto completion by using the “oc” command for both our simple user and how we can generate it system wide.

Regular user

For a regular user all we need to do is to log in as the user we want to use it and run the following command :

$ oc completion bash > ~/.bash_completion

Once the command is complete we can either log in and log out or we can source the newly created file :

$ source ~/.bash_completion

system wide

For “oc” bash completion to be available to us in a system wide manner we need to run the same command with root and send the output to our main bash completion directory under /etc/ to it’s own file :

# oc completion bash > /etc/bash_completion.d/oc.sh

Now each user on our system will be able to use oc <tab><tab> for their convenient.

custom completion

True , Red Hat provides us with tools which comes build in with the option to generate bash completion but some times we will want to auto complete command with different dynamic values and for that we will need to do a few more advanced operation.

host completion

We will start with a very simple bash auto completion where we maintain a hosts file (not /etc/hosts) and we want bash to auto complete the ssh command with the content of that file.

First let’s create such file :

$ touch ~/.hosts

Now let’s add a few host names to it :

# for host in "server1" "server2" "server3"; do echo $host >> ~/.hosts ; done

Next we will add to our .bashrc file the following line :

$ echo "export HOSTFILE=$HOME/.hosts" >> ~/.bashrc

Now all that is left is to tell bash to auto complete the ssh command with each line as it’s output.

$ echo "complete -A hostname ssh" >> ~/.bashrc

To see the magic happening disconnect and reconnect to the server or run the source command to your .bashrc file :

# source ~/.bashrc

Advanced Function

If we want… we can create auto completion which is a result of another command or even a bash function.

For example, if we are working with Kubernetes vanilla and we are using kubectl a simple task in openshift for changing the namespce require us the following command with kubectl :

$ kubectl config set-context --current --namespace=<namespace>

In order to make this command a bit shorted we can use bash function as the following example :

kubectl-set-ns() {
kubectl config set-context --current --namespace=$1
}

Now we can use the function to change the current namespace we are working on.

(example: switching to default)

$ kubectl-set-ns default

At this point we need to run a command to see all the namespaces and then select one and run the function to switch to that namespace.But what if we can do all of this in one command instead of 2 …

For that Bash is providing use with the “compgen” command with the right environment variable creates an output we can then use as an argument for our initail function.

First let’s create a new function which collects all the namespaces :

__kubectl_setns() {
COMPREPLY=($(compgen -W "$(kubectl get ns | awk 'NR>1 {print $1}')" -- "${COMP_WORDS[1]}"))
}

For the Last step all we need to do is to tell bash to auto complete our first function (kubectl-set-ns) with our second function (__kubectl_setns) by adding the following line to our .bashrc file :

complete -F __kubectl_setns kubectl-set-ns

Now we can login/logout to our bash session and run the command kubectl-set-ns with the <tab><tab> option.

That is it

If you have any question feel free to responed/ leave a comment.
You can find me on linkedin at : https://www.linkedin.com/in/orenoichman
Or twitter at : https://twitter.com/ooichman

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Oren Oichman

Oren Oichman

Open Source contributer for the past 15 years