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

HowTo: Cambiar el Idioma de Mac Os X

A algún conocido, al llevar su mac a reparar, le han tenido que reinstalar el sistema y al recogerlo se lo ha encontrado en inglés. Que es el idioma por defecto de la instalación.

Menú de Mac OS X en inglés

Siempre se puede llevar otra vez al servicio técnico para que nos lo vuelvan a volver a poner en Español, o si os da pereza, voy a explicar cómo podéis ponerlo en Español siguiendo unos sencillos pasos.

Abrir Preferencias de Idioma

Lo primero va a ser abrir las preferencias del Lenguaje e Idioma. Podemos acceder a las Preferencias del Sistema desde la barra de menú, arriba, pulsando en la manzana. Se despliega un menú en el que elegimos "System Preferences …".

Abrir Preferencias del Sistema

Una vez abiertas las Preferencias del Sistema, pulsamos "Language & Text".

Idioma y texto en Preferencias del Sistema

Elegir el idioma preferido

En la primera pantalla de las preferencias de idioma, tenemos un listado con los idiomas del sistema.

Lenguaje e Idioma

Ordenamos los idiomas poniendo arriba aquellos que queremos que se utilicen. Un programa leerá el primer idioma de la lista, por ejemplo «Español». Si el programa está traducido al Español, saldrá en Español, si no, leerá el segundo. Si el segundo es «Inglés» y la aplicación está traducida al Inglés, pues saldrá en Inglés, y si no, pues leerá el tercero, y si no, el cuarto …

¿Y cómo ordenamos la lista de idiomas para poner el Español primero? Busca el español en la lista, púlsalo y arrástralo hacia arriba.

Ordenar Idiomas

Para que el sistema salga en español, el Español debe ser el primero de la lista.

Español debe quedar por encima del Inglés

Si el español no aparece en la lista, pulsa en "Editar Lista", debajo de la lista. Busca el idioma Español y márcalo. También puedes desmarcar aquellos idiomas que no utilices, pero deja por lo menos el Inglés.

Reiniciar

Los cambios tendrán efecto la próxima vez que se abran las aplicaciones. La manera más sencilla de reiniciarlas es reiniciar el equipo entero.

Si no podemos, o no queremos en este momento, apagar el sistema, podemos cerrar una a una todas las aplicaciones. La única que no podemos cerrar es el Finder, ya que está siempre abierto. Si este es tu caso, sigue los siguientes pasos.

Pulsa la manzana en la barra superior y en el menú que se despliega selecciona "Force Quit …":

Abrir Forzar el cierre

Se muestra una ventana con el listado de las aplicaciones abiertas. Selecciona Finder y pulsa Relaunch.

Reiniciar Finder

Una vez que hayamos reiniciado, las aplicaciones aparecerán en Español:

Menú de Mac OS X en español

I’m twitting again

Yeah!! Twitter have reactivated my account :D. Good news!!

I’ve written a patch for my wordpress theme and now it reads the caption from twitter :D. I still have to fix some performance problems, but… here it goes:

require_once 'XML/Feed/Parser.php';
$feeds = fopen('http://twitter.com/statuses/user_timeline/26378338.atom','r');
$source = "";
if ($feeds) {
	while ($s = fread($feeds, 1024)) {
		$source .= $s;
	}
}
$feed = new XML_Feed_Parser($source,false,true,true);
$first_entry = $feed->getEntryByOffset(0);
$title = $first_entry->title;
$little_title = substr($title, 13, 30);
$little_title .= (strlen($title) > 43) ? '...' : '';
print "<a href=\"http://www.twitter.com/capitangolo\">$little_title</a>";

Updated:

Thanks to: http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/. Now my tweets are loaded by javascript, so my blog loads much fast :D.

gems – Terminal Broadcasting

We had a issue for the next Warp Talk. All the talk will be done with a shell as presentation tool. But people won’t see the text on the shell trough the cam, as it resolution is limited.

Isaac have found vía Debian package of the day Gems.

Gems allows exactly what we need, broadcast a terminal by tcp/ip. Screen would be the first thought, but a ssh connection from unknown people was needed :S.

To use gems, install it:

$ sudo aptitude install gems

If you want to broadcast a terminal, you type on that terminal:

golo@Macluzo:~$ gems-server -port 9999
gems-server initialized.

And now, you are broadcasting.

If you want to observe a terminal, type:

golo@Macluzo:~$ gems-client localhost 9999
gems-client: Connection established -- Press 'q' to exit.

Notice that localhost should be changed to the server’s host :D.

If you plain to attend this talk, follow our Twitter. We’ll publish server’s public address and port there.

Apache Authentication with eBox openLDAP

I’m using eBox to manage my server. eBox was mind for enterprise networks, but dns and email modules are very useful for a internet server.

eBox manages email users with openLDAP (slapd), so I wanted all the services in my server to use the same authentication.

This is the general configuration for apache authenticating with eBox, wich I use for my SVN repositories:

# LDAP Authentication & Authorization is final; do not check other databases
AuthzLDAPAuthoritative on

# Do basic password authentication in the clear
AuthType basic
AuthBasicProvider ldap

# The name of the protected area or "realm"
AuthName "Triangulo de las merluzas Subversion Repositories"

# Active Directory requires an authenticating DN to access records
# This is the DN used to bind to the directory service
# This is an Active Directory user account
AuthLDAPBindDN "cn=admin,dc=ebox"

# This is the password for the AuthLDAPBindDN user in Active Directory
AuthLDAPBindPassword "secret"

# Group Configuration
AuthLDAPGroupAttributeIsDN off
AuthLDAPGroupAttribute memberUid

# The LDAP query URL
AuthLDAPURL  "ldap://localhost:389/ou=Users,dc=ebox?uid"

# Require authentication for this Location.
# In this case, only developers can use the repository.
Require ldap-group cn=developers,ou=Groups,dc=ebox