(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 😉

(6) Bautizo

Una de las cosas más complicadas de empezar un proyecto es bautizarlo.

Parece mentira, pero empiezas a añadir condiciones, y luego es difícil encontrar un nombre:

  • Que tenga varios dominios libres
  • Que no se confunda con algo que ya exista
  • (corolario) Que tenga pocos resultados en google
  • Que tenga nombre libre en twitter
  • Que sea fácil de pronunciar / recordar
  • Que tenga algo de relación con el proyecto

Después de estar todo el día buscando nombres, al final ¡¡¡¡lo he encontrado!!!!

Bora Board

Ahora sólo falta hacer el proyecto… 😛

(5) Free Merluza

No sabía cuántas cosas tenía pendientes en mi servidor hasta que me he puesto a mirarlo por dentro.

Resulta que con la última actualización de ebox a zentyal, los repositorios de los proyectos dejaron de funcionar, entre otras cosas porque no actualicé la configuración del LDAP. Hoy he estado un buen rato actualizando los tracs y reconfigurando la autenticación.

La configuración de los repositorios subversion la hago a través de apache. Poco ha cambiado desde que escribí Cómo configurar apache para autenticar con el LDAP de Zentyal, sólo he tenido que actualizar la contraseña y los nombres de dominio.

Sin embargo, me ha sido imposible volver a configurar los tracs para que autentiquen correctamente. O yo no conseguía configurar los plugins que existen, o no funcionaban para la última versión de trac.

La solución ha sido sencilla (aunque no muy elegante). Utilizando el AccountManagerPlugin, hay una opción para autenticar mediante una ruta HTTP (HttpAuthStore). Lo que hace el servidor es llamar a una ruta http con el usuario y contraseña que da el usuario. Si la solicitud se lleva a cabo con éxito, el usuario está autenticado.

Perfecto! Como se configurar apache fácilmente para autenticar, puedo usar lo mismo para autenticar los tracs :D.

Wordpress Themes

Lo otro que he hecho hoy es un paso previo a la remodelación del css de esta web. Consiste en liberar todos los temas de wordpress que he hecho hasta la fecha. Utilizar un repositorio subversion me facilitará el actualizarlos, y ya de paso publico el código para quien quiera curiosear.

En fin… mañana más 😀

(3) sed valentín

Corazón

Hoy ha sido esa fiesta que consiste en demostrar tu amor abriendo la billetera. He aprovechado, y le he comprado a kimito unos cuchillos de cocina que nos hacían falta… ¡Soy todo un romántico!

Aparte de comprar el regalo, me he dedicado a limpiar el servidor donde tengo alojado mi blog y otras cosillas. En parte lo necesitaba para comenzar con un proyecto nuevo, y en parte forzado por @eckelon, que me ha pedido asilo cibernético.

Y es que los graciosos de 1and1 le borraron un servidor por falta de pago… aunque sí que había pagado. Así, de golpe, ni desactivar por si acaso, ni nada. Rollo Flickr pero a lo bestia. Así que estoy haciendo un poco de hueco para que pronto pueda volver al mundo bloguero.

Una de las cosas que llevaba tiempo queriendo hacer ha sido actualizar mi script de actualización de las DNS. Veréis, uso Zentyal para gestionar las DNS de mi dominio (y estoy bastante contento), peeeeero, tiene una pequeña limitación, y es que no acepta registros de tipo CNAME.

Así que este tipo de registros, los tengo que cambiar a mano en los archivos de configuración de bind. No es mucho problema, ya que con una línea se pueden añadir:

echo "foobar              CNAME   foobar.foo.com." >> /etc/bind/db.example.org

El problema estaba en que luego, tenía que editar a mano la línea del número de serie para que los servidores del mundo supieran que había cambiado mis dns. La línea es así:

                        2011021417      ;serial number

Hoy he tenido tiempo para poder automatizarlo, usando grep y sed. Ha quedado algo así (se aceptan mejoras :P) :


sernum=`cat $file_name | grep -o '[0-9]\{10\}\w*.;serial number' | grep -o '[0-9]\{10\}'`
sernum=$(($sernum+1))
cat $file_name | sed "/;serial number/s/\([0-9]\)\{10\}/$sernum/" > /tmp.db
cat /tmp.db > $file_name