(25) playing with bash autocompletion

Updated: as Blaxter notes, it’s necessary to open a new terminal after editing the bashrc file for the changes to take effect. Also, I’ve replaced the tail -n+2 with the -ss option. Thanks Baron Schwartz!

One of the things I’ve been doing lately is doing some cleanup on my laptop.

There are two things I’m constantly using on the shell:

  • Open a project folder
  • Connect to a MySQL Database

Bash Functions

I first made a bash function to help me with the projects paths:

function cdp {
case $1 in
  "foo")
    cd /Users/golo/devel/svn/foo/src ;;
  "bar")
    cd /Users/golo/devel/svn/bar/src ;;
  *)
    echo "Options:"
    echo ""
    echo "  foo"
    echo "  bar"
esac
}

I placed that on my /etc/bashrc , so I write:

$ cdp foo

And it takes me to the foo project folder.

But, as I have lot of open projects, I have to remember «foo» and «bar», or worse… ¡¡Write «foo» or «bar»!!

Bash Autocompletion

My Lazyness made me learn how to create bash autocompletions. This case is easy as executing «cdp» without parameters you get a list with all possible values. It’s easy to parse ;).

The autocompletor should be placed on the file /etc/bash_completion.d/cdp with this content:

_cdp_show()
{
        local cur opts

        cur="${COMP_WORDS[COMP_CWORD]}"
        opts=$(cdp | tail -n+2)
        COMPREPLY=( $(compgen -W "${opts}" ${cur}) )
}
complete -F _cdp_show cdp

opts stores all possible options (line per option), and cur stores the text to be autocompleted (not sure). compgen is a helper to create the autocompletion options, and complete is the command that does the autocompletion reading the COMPREPLY variable.

Now I get the following behavior:

$ cdp <tab><tab>
foo    bar
$ cdp f<tab>
$ cdp foo

Oh! Amazin!

MySQL Bash Autocompletion

¿What can be more awesome than that? Let me guess… ¡Autocompletion for mysql command!

The goal is to get autocompletion for the mysql databases. No more writing…

$ mysql information_schema

For that, we need a list of all databases on a parseable format, let’s try with SHOW DATABASES:

$ mysql -e "SHOW DATABASES"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
$ # Let's put this on a better format:
$ mysql -B -e "SHOW DATABASES"
Database
information_schema
mysql
performance_schema
$ # That's better, let's delete the table header:
$ mysql -B -ss -e "SHOW DATABASES"
information_schema
mysql
performance_schema
$ # We are ready! :D

Disclaimer: I tried mysqlshow but doesn’t accepts the Batch format, also I have the user and password on my /etc/my.cnf so this trick is not suitable for production environments.

Let’s create an autocompletor mixing this command with what we already know. The result is the file /etc/bash_completion.d/mysql:

_mysql_show()
{
        local cur opts

        cur="${COMP_WORDS[COMP_CWORD]}"
        opts=$(mysql -B -ss -e "SHOW DATABASES;" )
        COMPREPLY=( $(compgen -W "${opts}" ${cur}) )
}
complete -F _mysql_show mysql

Now you can use <tab>:

$ mysql i<tab>
$ mysql information_schema

Hope it helps! Improvements are welcomed 😉

Publicado por

GoLo

Bored of Universisty, I began to learn by my self trying to improve my skills. Then I met programming, Java and Linux. When I have some time, I work on my personal projects.