(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 ;)

5 Respuestas a “(25) playing with bash autocompletion”

  • #1 blaxter

    Do not forget to start another console after create the /etc/bash_completion.d/mysql file, it’s not magic (well, a little)

  • #2 Baron Schwartz

    You can also use “mysql -ss” to avoid the column header, so you don’t have to use tail. Good post!

  • #3 golo

    @Blaxter: important point!
    @Baron Schwartz: thanks! I didn’t knew that option :D.

  • #4 Gerry

    If you store the credentials in ~/.my.cnf, then it becomes suitable for production servers as long as you have don’t have shared accounts. Remember to make ~/.my.cnf only accessible/owned by you!

    Mis $.02
    G

  • #5 exekias

    Loved that MySQL autocompletion! Very nice!

    For project folder issue, you may be intersted in AutoJump ;) It’s very handy if you need to jump between a lot of folders/projects

Leave a Reply