Pequeñas herramientas para grandes necesidades ~ Aug 31, 2007
Pequeñas herramientas para grandes necesidades
La Columna.pl #2
Pequeñas herramientas para grandes necesidades
Se han pasado muy rápidamente estos últimos 15 días. Entre algunas pláticas, trabajo y otras cosas, pareciera que el tiempo simplemente se esfuma tan, tan rápidamente.
Como sea, ya estamos en la segunda entrega de La Columna.pl. En esta quincena quiero tocar un tema bien interesante que son esas pequeñas herramientas que nos pueden llenar de una manera muy especial alguna de nuestras necesidades. ¿Hay algo por ahí que quieras automatizar pero no te decides? Inténtalo.
El ejemplo que voy a poner aquí es acerca de una pequeña utilidad que hice para revisar el estado de la batería de mi laptop. Como es bien sabido por algunos de ustedes, amables lectores, utilizo una máquina PowerBook G4, sobre Debian GNU/Linux: En esta máquina hago la mayoría de mi trabajo, que se basa principalmente en desarrollo de software y algo de administración de sistemas. La mayoría de mi trabajo lo hago en esta máquina que es casi tan estable como una piedra. En fin, las computadoras Apple, como ésta, utilizan un microcontrolador que gestiona las funcionalidades de energía, tales como el control de suspensión, el nivel de batería y otras similares, llamado PMU. Lamentablemente las aplicaciones actualmente existentes que monitorean los atributos de PMU, en Linux sobre estas computadoras no me satisfacen del todo: Algunas son unas aplicaciones en GTK verdaderamente estorbosas; otras están integradas al panel de control de GNOME o KDE, del cual no utilizo ninguno. Opté por utilizar el control de batería de GKrellM, que es algo modesto, pero que de todas formas a veces no quería tener siempre en mi escritorio – que para empezar, no es que tenga un escritorio como tal, pues de un escritorio sólo utilizo algunos escritorios virtuales y algo de soporte de systray. Finalmente no estaba muy seguro de lo que necesitaba. Lo único seguro era mi inseguridad en el caso ![]()
¡Una pequeña aplicación en Perl! Claro, desde un emulador de terminal podría llamar esta aplicación y me diría qué porcentaje tengo de batería restante en mi máquina, sería lo más simple, sencillo y a mi gusto, sería perfecto. Pues vamos a poner las manos a la obra.
En mi máquina, la información de la batería se encuentra en /proc/pmu/battery_0, que luce así:
flags : 00000011 charge : 3535 max_charge : 3537 current : 0 voltage : 12495 time rem. : 0
El archivo indica diferentes valores para amperaje y voltaje. Los que me interesan son los valores de charge y max_charge que indican miliampers/hora de la carga actual que tiene la pila y la máxima.
Lo que hay que hacer es bastante simple. Obtener el valor de charge, el de max_charge y obtener un porcentaje del primero con respecto al segundo. En esta columna tocaré algunos temas básicos pero que pueden ser de utilidad para entender algunos conceptos más adelante en otras columnas.
#!/usr/bin/perl use warnings; use strict;
Mando llamar al intérprete de Perl que en la mayoría de las distribuciones con binarios precompilados irá a dar a /usr/bin/perl e inmediatamente mando llamar dos pragmas de Perl: El primero, warnings, para controlar advertencias y el segundo, strict, para restringir construcciones inseguras. Es bueno siempre llamar ambos pragmas para educarnos un poco al programar. Un pragma es únicamente un indicador para el momento de la compilación, podremos estudiar un poco los pragmas en futuras columnas.
my $pmufile = '/proc/pmu/battery_0';
Declaro la variable $pmufile que indicará la ruta absoluta del archivo que mencionaba anteriormente.
my $filecont; {
local $/ = undef;
open(PMU, $pmufile) or die $!;
$filecont = <PMU>;
}
Aunque el uso de local ya no se aconseja mucho, es bueno a veces para utilizarlo en bloques específicos donde sólo tengamos que modificar, quizás, una variable especial, como en este caso, la variable especial $/. Esta variable nos sirve para definir el input record separator, que por default, es una línea nueva. Modificarlo nos permite hacer cosas interesantes, sobre todo cuando efectuamos un ciclo while() hacia un filehandle. En este caso, indefinimos su valor, por lo cual, luego de abrir el archivo $filename a lectura, vaciamos todo el contenido del archivo en una sola variable, $filecont, que habíamos declarado antes del bloque. En alguna columna futura tengo pensado tratar a fondo las variables especiales, que son algo muy interesante dentro de Perl.
my($charge) = $filecont =~ /charges+:s(d+)/; my($max_charge) = $filecont =~ /max_charges+:s(d+)/;
Aquí creamos las variables $charge y $max_charge y les asignamos el valor que nos arroja nuestra expresión regular como la variable especial $1, en ambas líneas.
my $porc = int (($charge/$max_charge) * 100);
Dividimos $charge entre $max_charge y multiplicamos el resultado por cien, para obtener el porcentaje. Sin embargo, este resultado nos arrojaría más de diez decimales, después del punto. Por ello, utilizamos la función de Perl, int, que nos regresa el valor entero de su parámetro (mi incipiente naturaleza matemática me hace hacer notar que un número entero no es necesariamente un número natural
).
print "t", "Restante: $porc %", "n";
print
en realidad requiere una lista como argumento, lo que generalmente hacemos en enviarle un sólo parámetro (por ejemplo, print "Hola mundo";), sin embargo, para una notación mucho más intuitiva, ponemos el salto de línea y el tabulador como primer y tercer parámetro, una lista, precisamente.
¡Y listo! Le agrego un bit de ejecución al script, lo renombro a pila, lo pongo en /usr/local/bin o algo similar y puedo correrlo fácilmente:
damog@cochina:~$ pila Restante: 86 % damog@cochina:~$
Ya luego podría usar ese comando para hacer otras cosas: parsear el valor y podría enviarme un correo avisándome que ya se me va a acabar la pila, o mandar un mensaje al systray o quizás conectarme al IRC y avisarle a mi nick al respecto; hay muchas cosas más que Perl nos facilita hacer, ¡tu imaginación es el límite!
De otras muchas formas habríamos podido abrir el archivo y leer el contenido de charge y max_charge. ¿Tú de qué forma lo hubieras hecho? ¿Quizás ciclar el filehandle hasta toparse con /^max_charge/? ¿Quizás usar alguna combinación con ejecución externa de cat o de grep?
Te invito a que me envíes tus comentarios. Nos leemos dentro de quince días.
Referencias útiles
- http://perldoc.perl.org/index-pragmas.html
- http://perldoc.perl.org/perlvar.html
- http://perldoc.perl.org/functions/int.html
- http://perldoc.perl.org/perlop.html#Integer-Arithmetic-integer
Autor
Durante el día, David Moreno Garza (http://www.damog.net/) desarrolla aplicaciones, sistemas y proyectos para una incipiente empresa internacional de telecomunicaciones; adicionalmente es consultor independiente en empresas mexicanas y extranjeras utilizando Perl. Durante la noche intenta salvar al mundo del mal usando expresiones regulares y netiquette.
Licencia de uso
Copyright © 2007 David Moreno Garza.
This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/).
Sobre La Columna.pl
La Columna.pl
es una columna quincenal que escribe el autor alrededor de Perl. Está inspirado en las columnas que Randal L. Schwartz ha escrito desde hace varios años ya. Por medio de recetas, consejos, instructivos y guías, el autor pretende propiciar interés en la gente para que conozca un poco más a fondo este apasionante lenguaje de programación y así fomentar una comunidad más sólida alrededor de él.
Visite http://www.damog.net/columnapl.



