lunes, 17 de agosto de 2015

Localizar ficheros en Linux

Un programa que me parece una maravilla en Windows es Everything, y no he encontrado nada en Linux que se le parezca. No concibo una sesión de trabajo en mi ordenador Windows sin este programa. Ojalá aparezca algo similar para Linux.

Pero no todo está perdido en Linux. Aquí tenemos el programa locate, con el que podemos hacer cosas "parecidas" (aunque ya quisiera yo que tuviera la potencia y el bajo impacto en memoria y procesador que tiene Everything).

Un ejemplo: para localizar todos los ficheros de configuración de MySQL que hay en mi equipo, escribiría algo así:

$ locate my.cnf

Y la salida es algo como esto:

Fig. 1. Localizando todos los ficheros "my.cnf" en mi equipo

Si además quiero abrirlos todos ellos en un único paso, podemos hacer

$ locate my.cnf | xargs gedit

Y se nos abriría una ventana como esta

Fig. 2. Todos los ficheros my.cnf abiertos en gedit

Ojo: esto funciona porque gedit acepta múltiples parámetros en la línea de invocación. Si el visor que vamos a utilizar no soporta múltiples parámetros, habría que hacerlo de otra manera.

El nombre que se le pasa como argumento a locate es un patrón, no tiene por qué ser el nombre literal. Esto quiere decir que buscará ficheros que contengan el patrón especificado en su nombre. Por ejemplo, podríamos haber listado los ficheros anteriores tecleando un carácter menos:

$ locate my.cn

Y el resultado sería el mismo, ya que los ficheros implicados CONTIENEN el patrón especificado

Fig. 3. Todos los ficheros my.cn* del equipo

Fijaos que el patrón no es exactamente una expresión regular, ya que no hace falta poner el * para indicar que puede haber más caracteres después de la "n" y, sin embargo, así es cómo locate hace la búsqueda.

Si elimino la letra "n" del patrón, podemos ver que aparecen más ficheros

Fig. 4. Aparecen otros ficheros que coinciden con el patrón *my.c*

O sea, que es como si el patrón tuviera al principio y al final un * (o, para los que estáis más habituados al mundo SQL, como si se hiciera una búsqueda LIKE '%PATRON%')

Así, por ejemplo, si quiero buscar todos los ficheros JPG que tengo en el equipo, no hay que buscar con el patrón *.jpg, sino simplemente teclear

$ locate .jpg

Fig. 5. Listado de ficheros .jpg existentes en mi equipo

Y si lo que quiero es contar cuántos ficheros JPG tengo en el equipo, puedo añadir esto:

$ locate .jpg | wc -l

Fig. 6. ¿Más de 2.000 imágenes????



Si queremos, podemos utilizar expresiones regulares en el patrón utilizando la opción --regex. Así, para buscar todas las imágenes JPG que empiezan por "yellow" pondríamos algo como

$ locate --regex yellow.*.jpg

Y el resultado, en mi equipo, son dos ficheros

Fig. 7. Las imágenes JPG que comienzan por "yellow*"

Que podríamos haber abierto así:

$ locate --regex yellow.*.jpg | xargs eog

Ojo: he utilizado como visor de las imágenes eog (Eye of Gnome) ya que éste soporta múltiples ficheros en una invocación. Sin embargo, shotwell, el visor por defecto de Ubuntu, no los soporta y daría un mensaje diciendo que hay parámetros de más en la invocación.

Al contrario que Everything, que monitoriza el sistema de ficheros constantemente (algo posible gracias al journal de NTFS), la base de datos de locate no se actualiza con tanta frecuencia. Ahora no tengo tiempo de investigarlo, pero me da a mí que se actualiza en cada reinicio del sistema. Lo que sí se puede hacer es actualizarla a mano con el comando updatedb:

Fig. 8. Actualizar a mano la BD de locate

(Lo de "sudo" he tenido que ponerlo porque si no me daba problema al crear algún fichero temporal).



Bueno, pues dicho todo lo anterior, ya podéis buscar rápidamente todos esos ficheros que os gustaría renombrar, por si las moscas...

Fig. 9. Ficheros que hay que renombrar urgentemente

miércoles, 12 de agosto de 2015

Notificaciones en Ubuntu

El escenario

Llego al curro y me dicen que durante mi ausencia me ha llamado Claudia Schiffer para ver si le puedo hacer una sesión de fotos y darle cremita, que le apetecía a la zagala irse a la playa. Como no me ha localizado, ha pedido que por favor le devuelva la llamada, pero a una hora concreta, ya que cuando me llamó Claudia se iba a cortarse las uñas y no podría contestarme durante un rato. La hora a la que me ha dicho que la llame es dentro de 20 minutos.

Yo llego, me siento delante de mi ordenador a buscar en Google fotos de Claudia trabajar y espero ansiosamente tranquilamente a que pasen los 20 minutos para llamarla. Probablemente no se me olvide (la Schiffer no me llama todos los días), pero puede que quiera asegurarme de no olvidarlo. Puedo ponerme una alarma en el móvil, pero, ya que voy a estar trabajando con el ordenador ¿no sería mejor que me saltara un aviso en pantalla dentro de 20 minutos?

Hay varios programas en una distribución estándar Ubuntu que podemos utilizar para mostrar un mensaje. Combinando estos con sleep (esperar X segundos, en este caso los 20 minutos equivalen a 1200 segundos), puedo hacer esto que acabo de explicar. Los comandos que siguen están probados en una instalación estándar de Ubuntu 15.04. En todos los casos, abriré una consola, me mandaré el aviso y a continuación me pondré a "trabajar" en una hoja de cálculo, a esperar a ver qué pasa con la notificación.

1. notify-send


$ sleep 1200; notify-send "Llama a Claudia que te está esperando"

Esto mostrará uno de esos mensajes "globo" que aparecen en la esquina superior derecha de la pantalla y desaparecen al cabo de unos pocos segundos (Fig. 1).


Fig 1. Un globo avisándome de que tengo que llamar a mi musa

Como se puede ver en la captura de pantalla, para la prueba de concepto he cambiado el número de segundos a 4, pero esto no afecta para nada a la discusión.

El problema puede ser que la notificación de globo, al no quitarle el foco a la ventana en la que estemos actualmente, sigamos concentrados en la pantalla y no lo veamos (aunque reconozco que es un poco difícil no verlo, la verdad).

2. xmessage

$ sleep 1200; xmessage "Llama a Claudia que te está esperando"

Esto hará que salte un diálogo con un botón aceptar ("okay" en mi distro). Esta sí que roba el foco, así que no podemos ignorarla sin más. Eso sí, es posible que si con el ratón hacemos clic en otra ventana, la notificación quede tapada. Un problema que puede que hayáis apreciado es que la tilde del mensaje no sale correctamente. Normalmente, el mensaje saldrá en una esquina inferior (en diversas pruebas me ha salido tanto en la esquina inferior derecha como en la izquierda, sin que yo sepa muy bien por qué). Podemos usar la opción -center para que salga en el centro de la pantalla (Fig. 2).

Fig 2. Mensaje en el centro de la pantalla.¡Mis tildes!

3. zenity


El comando zenity permite lanzar diversos tipos de cuadros de diálogo desde nuestros scripts o desde una consola. El programa 'gdialog' es un envoltorio sobre 'zenity', así que mejor usar zenity directamente.

Estos diálogos pueden ir desde mostrar un simple mensaje al usuario (opción --info) hasta pedirle que introduzca algunos datos (un texto, una fecha [opción --calendar], elegir una opción de una lista...). Los valores devueltos por zenity se pueden capturar en el script invocante y asignarlos a una variable, por ejemplo, para trabajar con ellos (muy interesante).

Para mostrar un simple mensaje sin interés en capturar la salida, podríamos escribir algo así como:

$ sleep 4; zenity --info --text="Llama a Claudia que te está esperando"

Y veríamos algo similar a lo que se ve en la Fig. 3.

Fig. 3. Un diálogo de mensaje con zenity. Es tímido, se queda detrás

El problema es que zenity NO adquiere el foco, así que queda detrás de la ventana activa. Si ésta ocupa toda la pantalla... malo. También podéis ver en la fig. 3 que aparece un warning en consola. Esto no es un problema, pero no me gusta.

4. Conclusión


Tras unas cuantas pruebas, mi preferida para este tipo de recordatorios es notify-send combinada con sleep, pues me gustan esos globos que no interrumpen el trabajo y que son suficientemente visibles. Además, no hay que pasar ningún parámetro para que funcione bien, con lo cual es rápido de teclear y no hay que andar recordando opciones (o mirando la ayuda) como en zenity, por ejemplo.

Si tuviera que capturar información del usuario (un texto, el botón pulsado...) utilizaría seguramente zenity.

En cualquier caso, echadle un vistazo a la ayuda de las tres herramientas, que son altamente configurables. También existen muchas otras herramientas para hacer cosas parecidas, así que si éstas que os he presentado aquí no os resuelven del todo vuestros problemas, investigad un poco.

Bueno, os dejo, que ha llegado la hora de llamar a Claudia...¡ains, qué nervios!