jueves, 27 de febrero de 2014

Definiciones de Wikipedia en la terminal

Hoy voy a compartir una función para Bash que he elaborado esta semana con el objeto de poder consultar cómodamente desde la línea de comandos definiciones de ciertos términos en Wikipedia (en inglés, más que nada por la calidad de la información sobre temas técnicos que suelo consultar). He optado por una función de la shell en lugar de un script del estilo de drae, diccionario RAE de línea de comandos recientemente publicado, debido a la corta extensión del código, basado principalmente en una tubería de comandos:

function wps {
    if [ $# -eq 0 ]; then
        return
    else
        params=$*
        q=${params// /_}
    fi
    wget -qO - http://en.wikipedia.org/wiki/$q |\
    sed '/<table class="infobox/,/<\/table>/d' |\
    grep -m1 '<p>.*</p>' |\
    sed -e 's/<p>/\n/' -e 's/<\/p>/\n/' \
        -e 's/<[^>]*>//g' -e 's/\[[^]]*\]//g' |\
    sed -e 's/[0-9A-Za-z, ]*may refer to[:a-z ]*/ Ambiguous term/' \
        -e 's/[0-9A-Za-z, ]*can mean[:a-z ]*/ Ambiguous term/'
}

Paso a analizar los "ingredientes" usados:
  • La estructura condicional es para finalizar si no hay argumentos de línea de comandos y si los hay formatearlos para la posterior consulta en Wikipedia usando la sintáxis adecuada en el URL.
  • Se ejecuta wget para recuperar de forma silenciosa el documento web correspondiente al URL recién construido. El contenido HTML del mismo es el que se pasa por la tubería a los siguientes comandos, que hacen de filtros.
  • El primer sed elimina la tabla informativa que hay en ciertos artículos y que suele estar al principio del contenido; no nos interesa la información que resume y además estorba para recuperar el primer párrafo.
  • El comando grep lo usamos para seleccionar el contenido del primer párrafo "normal" en el contenido del artículo; es el resumen que queremos extraer.
  • El segundo sed incluye varias reglas de edición encaminadas a sustituir las etiquetas de párrafo por saltos de línea (para formatear la salida por pantalla) y a continuación eliminar el resto de etiquetas HTML y de anotaciones o referencias entre corchetes.
  • El último sed se encarga de detectar los casos en que el término es ambiguo (existen diversas acepciones con sus artículos correspondientes) para mostrar un mensaje de error genérico más adecuado. En este caso el usuario debería concretar más: por ejemplo, en lugar de ejecutar wps bash, ejecutar wps bash shell.
En fin, se trata de una muestra más de la potencia de la shell Bash a la hora de combinar comandos y utilidades preinstaladas en cualquier sistema Linux para crear nuevos comandos que proporcionen información útil en un segundo, aunque esta se encuentre alojada en un servidor al otro lado del mundo...

viernes, 14 de febrero de 2014

Fundamentos de la filosofía Unix

Recientemente he estado ojeando un libro (el último hasta la fecha) de Eric S. Raymond, autoproclamado hacker (en el sentido clásico, no confundir con cracker) portavoz del movimiento open source y antropólogo de la subcultura hacker alrededor de Unix e Internet (no en vano es desde hace años editor del Jargon File, publicado en papel como New Hacker's Dictionary). Se trata de la obra titulada "The Art Of Unix Programming" (disponible en PDF buscando un poco en Google).

El libro es muy recomendable (al menos algunas de sus partes, otras pueden ser demasiado técnicas y/o filosóficas) para cualquiera interesado en los sistemas Unix (incluyendo sus descendientes modernos como Linux y FreeBSD) y la filosofía y principios de diseño que se destilan de su legado de más de 40 años. Además puede ser de interés para cualquiera dedicado al desarrollo de software, ya que del mismo pueden extraerse numerosas enseñanzas y reflexiones valiosas a la hora de diseñar un programa, no sólo para entornos tipo Unix.

Como muestra, quería traducir el conjunto de reglas que según el autor resumen los fundamentos de la filosofía Unix a la hora de escribir programas y que pueden encontrarse en su primer capítulo. Espero que "iluminen" a alguien:
  1. Regla de la Modularidad: escribe partes sencillas conectadas por interfaces limpias.
  2. Regla de la Claridad: la claridad es preferible al ingenio.
  3. Regla de la Composición: diseña programas para que puedan conectarse a otros programas.
  4. Regla de la Separación: separa las políticas de los mecanismos para aplicarlas.
  5. Regla de la Sencillez: diseña con la sencillez como objetivo; añade complejidad solo cuando sea necesario.
  6. Regla de la Parsimonia: escribe un programa grande cuando esté claro que nada más funcionará.
  7. Regla de la Transparencia: diseña con la visibilidad como objetivo para facilitar la inspección y la depuración del código.
  8. Regla de la Robustez: la robustez es hija de la transparencia y la sencillez.
  9. Regla de la Representación: incorpora el conocimiento a los datos para que la lógica del programa pueda ser estúpida y robusta.
  10. Regla de la Mínima sorpresa: al diseñar la interfaz de usuario haz siempre lo menos sorprendente.
  11. Regla del Silencio: cuando un programa no tenga nada interesante que decir no debería decir nada.
  12. Regla de la Reparación: cuando un programa deba fallar, que lo haga ruidosamente y cuanto antes.
  13. Regla de la Economía: el tiempo de un programador es caro; ahórralo en lugar del tiempo de la máquina.
  14. Regla de la Generación: evita las soluciones manuales; escribe programas para generar programas cuando sea posible.
  15. Regla de la Optimización: prototipa antes de perfeccionar. Haz que funcione antes de optimizarlo.
  16. Regla de la Diversidad: desconfía de cualquiera que asegure que solo hay una forma correcta.
  17. Regla de la Extensibilidad: diseña para el futuro porque llegará antes de lo que piensas.