Bueno, pues ha pasado otro año. La web de CRySoL (tal como la conocemos hoy) cumple 3 años ya. Se inauguró el 20 de octubre de 2005. Aunque como muchos sabéis había algo parecido a una web cutre desde unos años atrás.
A veces puede resultar útil poder programar el sistema para que realice tareas a una hora determinada. En esta receta veremos dos maneras de hacerlo.
at
La utilidad at nos permite ejecutar tareas a una determinada hora. Si no la tenéis en el sistema, basta con instalar el paquete at de la manera estándar.
Por ejemplo, vamos a programar que aparezca el eye-of-gnome a las 12:05. Para ello, ejecutamos en un terminal el comando at, indicando a continuación la hora a la que debe comenzar la tarea. Como veréis, aparece un prompt en el que indicaremos las tareas que queremos que se ejecuten, una por línea. Para salir del prompt, hay que pulsar Ctrl+D. Aparecerá un mensaje confirmando la hora y el número de la tarea (job).
A menudo, lo que queremos es ejecutar varias tareas, pero en un orden secuencial, no todas a la vez (vamos, lo que viene siendo un script). Suponiendo que queramos ejecutar mistareas.sh, haremos lo siguiente:
También se podría poner miscript.sh como una tarea en el modo interactivo del prompt, siempre y cuando tenga los permisos adecuados de ejecución.
Cabe destacar que con at, las tareas quedan programadas para una sola vez, y se borran después de ejecutarse. Es decir, al día siguiente no volverán a ejecutarse.
Si queremos borrar una tarea que tenemos programada, debemos conocer primero su número (el que sale al programarla). Para borrarla, utilizamos atrm. Si no conocemos el número de la tarea o lo hemos olvidado, podemos consultar las tareas programadas con la opción -l:
cron
Cron es una herramienta que permite la ejecución de tareas periódicamente en varios intervalos: horario, diario, semanal y mensual. Su utilización es más sencilla que la de at: Basta con guardar el script que queramos ejecutar (éste no tiene modo interactivo) en el directorio correspondiente a cuándo queremos que se ejecute.:
Cada hora: /etc/cron.hourly/
Cada día: /etc/cron.daily/
Cada semana: /etc/cron.weekly/
Cada mes: /etc/cron.monthly/
Esta simplificación de uso es específica de Debian (y derivados quizá). Aunque la funcionalidad es posible conseguirla en otras distribuciones, no es tan sencillo (y puede que los directorios mencionados no existan).
Para saber exactamente cuándo se van a ejecutar las tareas, echamos un vistazo al fichero /etc/crontab. Éste es el mío:
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
Las columnas indican lo siguiente:
m = minute (minuto)
h = hour (hora)
dom = day of month (día del mes)
mon = month (mes)
dow = day of week (día de la semana)
Por lo tanto, mi crontab indica que:
- Las tareas "horarias" se ejecutarán en el minuto 17 de cada hora.
- Las tareas diarias se ejecutarán a las 6:25
- Las tareas semanales se ejecutarán el séptimo día de la semana, a las 6:47 (0 y 7 indican Domingo, 1 es Lunes, etc...)
- Las tareas mensuales se ejecutarán el día 1 de cada mes, a las 6:52
Cómo escribir reglas para udev permitiendo a dispositivos USB ser usados sin necesidad de ser root
Introducción
A veces sucede que quieres utilizar un dispositivo USB un poco "exótico" y resulta que no puedes utilizarlo sin ser root. Un ejemplo de ello puede ser dfu-programmer o pk2, que son aplicaciones no muy estándard y por lo tanto no se les ha dado el soporte necesario, haciendo que haya que invocarlas como root si queremos utilizarlas.
La solución para ésto pasa por crear unas reglas para udev que permitan que éstas aplicaciones accedan al puerto USB de nuestro PC en modo normal.
Un ejemplo: dfu-programmer
Ilustraré el proceso con una aplicación de ejemplo: dfu-programmer. Se trata de un cliente para el bootloader USB instalado en los micros con soporte para dicho interfaz de Atmel.
Para añadir las reglas, abrimos (mas bien creamos) el archivo que contedrá dichas reglas:
En este archivo, deberemos escribir algo tal que así:
Básicamente lo que se hace es indicar a udev que dfu-programmer usa el sistema USB, dando información detallada acerca del vendorID y el productID del dispositivo que se va a conectar al puerto. También indica con qué permisos se debe acceder al puerto y especifica el grupo cuyos permisos hereda la aplicación.
En esta receta se explica cómo hacer downcasting de los elementos de un contenedor a una clase más derivada.
Introducción
Supongamos que tenemos la siguiente jerarquía (nos servirá a lo largo de toda la receta):
El vector de B's y C's
En muchas ocasiones, utilizamos los contenedores de C++ (como vector, stack...) para almacenar distintos tipos de datos. Por ejemplo, imagina que queremos tener un 'vector' que contenga tanto instancias de 'B' como de 'C'. En C++ es necesario crear un vector de la clase padre de ambas, o sea, un 'vector' de A's. Un pensamiento ingenuo (como el mío), implementaría esto mismo así:
¡Y compila!. Lo que está ocurriendo es legal, pero realmente no es lo que queremos ya que el compilador "trunca" el objeto para añadirlo al contenedor y satisfacer el tipo del vector. Este proceso se denomina "Object Slicing". De esta forma, NO estas incluyendo en el vector objetos de tipo 'B' o 'C', sino que todos son de tipo 'A' y, por lo tanto, cuando quieras recuperarlos te encontrarás con que no es posible hacer el molde a tipos más derivados (esa es la sorpresa de la que habla el comentario del texto :-)).
Solución
Antes de dar la solución, vamos a pensar qué queremos realmente. Queremos tener un contenedor que tenga varios tipos de objetos. Hemos visto que el compilador hace slicing de los objetos si estos son instancias. Pero si lo que introducimos en el contenedor son referencias a los objetos, el Object Slicing no ocurre, por lo que tendremos los objetos completos para luego hacer el downcasting.
De esta forma, el código correcto sería el siguiente:
Como puedes ver, para hacer el downcasting C++ ofrece el operador dynamic_cast. Es necesario que las clases que intervienen en el casting dinámico estén "en una jerarquía polimórfica real", es decir, la clase padre tiene que tener, al menos, un método virtual.
Esta receta es una pequeña introducción al soporte de Python para diseño orientado a objetos. Para programadores noveles, se aconseja primero la lectura de nuestra ya veterana receta Mini tutorial de Python.
El próximo 17 de Octubre finaliza el periodo de inscripción al II Concurso Universitario de Software Libre de Castilla-La Mancha y ¡¡Queremos Animarte a Participar en esta Nueva Edición!!
Los nuevos tiempos del ECTS y el espacio europeo traen nuevos “aires” a la vida universitaria. Esta nueva metodología docente aboga por la evaluación continua y el control del progreso del alumno a lo largo del curso. Eso ya se estilaba en mi cole cuando hice la EGB, tampoco es que sea nada innovador.
Aquí tenéis un artículo muy interesante sobre la oferta de sistemas operativos disponibles. Si queréis ser originales de verdad, dejarsen de Güindor, de Linus y de macoesequis, y probad alguno de estos: