viernes, 30 de enero de 2009

Tareas complejas con HAL

Recordemos que el último paso de ayer, el que nos permitió construir la orden final

dict -d spa-eng bye

consistió en un acto realizado por la mano del hombre, la selección del nombre de diccionario spa-eng dentro de la lista bimembre:

eng-spa English-Spanish Freedict dictionary
spa-eng Spanish-English Freedict dictionary

Hay multitud de situaciones en la que este último reducto de actividad humana puede ser también eliminado y efectuado directamente por HAL. Veamos un ejemplo.

Supongamos que en nuestras búsquedas en diccionarios tenemos conocimiento seguro de la existencia de uno ---porque lo hemos usado otras veces---, pero cuyo nombre no recordamos ahora. Digamos que se trata de un diccionario sobre computación (computing en inglés).

Si procedemos como el día pasado, tendríamos que realizar los siguientes pasos:

  1. Buscar la línea referente al diccionario en cuestión en la lista entera de diccionarios:

    dict -D | grep -i 'computing'

    que devuelve [El uso del signo ¶ es premeditado, indica la existencia de un espacio en el comienzo de la línea. Más tarde veremos la razón de hacerlo visible]:

    ¶foldoc The Free On-line Dictionary of Computing (27 SEP 03)

  2. Ejecutar la orden dict dando a la opción -d el argumento foldoc, por ejemplo:

    dict -d foldoc debian


HAL se sentirá incómodo si seguimos esta estrategia. El segundo paso es perfectamente prescindible. Porque, aunque no lo parezca, no es necesario que intervengamos en ningún momento del proceso de construcción de la orden final.

Acallemos el orgullo herido de HAL y empecemos desde el principio, en la ignorancia del nombre de diccionario que nos interesa.

Antes de nada debemos realizar una reflexión metodológica previa de suma importancia. Es fundamental plantear metódicamente cada tarea que se emprenda de acuerdo a los principios de análisis y síntesis. El paso inicial es siempre el análisis del problema, su descomposición en partes. Cada una de estas partes constituye a su vez un problema que debe resolverse independientemente, en pasos sucesivos. El ataque final consiste en la síntesis de las soluciones parciales, que se efectúa mediante tuberías o dispositivos análogos. Que este tipo de estrategia sea común a muchas de las tareas no triviales que planteamos a HAL tiene su razón de ser en su propia arquitectura. Los creadores originales de HAL eran fanáticos defensores de una máxima: que cada herramienta haga una sola cosa, sencilla, pero bien hecha, y que las herramientas complejas resulten de la composición de herramientas simples. Se las apañaron para que las herramientas simples fuesen lo suficientemente flexibles como para pudiesen engarzarse una con otra y se generasen a partir de ellas herramientas complejas. Las tuberías son el ejemplo más destacado, quizá, de este tipo de planteamiento. Nótese que, en el fondo, este es el principio dominante de todas las ingenierías y de una buena parte del pensamiento humano.

Miremos, pues, con estos ojos, el problema que tenemos delante, la construcción de la orden siguiente:

dict -d XXXX 'computing'

Las XXXX designan lo que no sabemos, el diccionario que queremos consultar, un diccionario sobre computación de cuya existencia estamos seguros, pero cuyo nombre no recordamos.

Sabemos, además, que estas XXXX ---el nombre de un diccionario--- han de ser forzosamente una de las palabras que aparecen en la primera columna de la lista que genera dict -D, dado que cada línea de tal lista tiene el formato característico:

¶NOMBRE-DICCIONARIO DESCRIPCIÓN

[En realidad, en el caso presente no hay un único espacio de separación entre NOMBRE-DICCIONARIO y DESCRIPCIÓN. Pero vamos a pasar por encima de este detalle para no complicar las órdenes que vamos a utilizar más tarde. En todo caso, el resultado va a ser el mismo.]

Podemos obtener con grep una línea de esa lista, realizar, por así decir, un corte longitudinal en la lista. ¿Pero es posible obtener de una línea con un formato tipificado como el anterior alguna de sus columnas, en concreto, únicamente la primera? ¿Es posible realizar cortes transversales en ella? De ser así, habríamos dado un paso adelante en nuestro objetivo. Si lo lográsemos, aún quedaría otro paso que dar, conseguir que el resultado del corte transversal se introdujese en el lugar que corresponde en la orden final, o sea, en lugar de las XXXX.

Resolvamos el problema por partes, justo las que han surgido de nuestro análisis.

La primera es conseguir cortes transversales de líneas con varias columnas o campos (fields). HAL tiene una tijera especializada para realizar esta operación, la orden cut. Funciona de la siguiente manera: se le indica a HAL el carácter que sirve para delimitar cada campo de las correspondientes líneas (con la opción -d de cut) y se le pide que nos devuelva los campos que nos interesan (con la opción -f de cut) [los campos se identifican por su posición en la lista: el primer campo empezando por la izquierda es el número 1; el segundo, el número 2; etc.]:

Por tanto,

cut -d' ' -f1

devuelve la primera columna o campo de la línea o líneas que se le suministren a cut como entrada, donde cada campo está separado del siguiente por un espacio, que, como de costumbre entrecomillamos: ' '.

De igual forma que grep, cut puede tomar sus datos de entrada de cualquier parte, por ejemplo, de un fichero, pero también del propio dispositivo de entrada por defecto ---la cañería principal, ¿se recuerda? Probemos esto último:

cut -d' ' -f2

Tras el Enter, procedemos a alimentar a cut:

Hola cut
cut # cut devuelve el segundo campo
Ctrl+D

(como el día pasado, con Ctrl+D salimos del experimento.)

Antes de seguir con la segunda parte del problema ---y para que el lector no se pierda luego--- sinteticemos provisionalmente las piezas con las que ya contamos. Son las siguientes:

  1. dict -D nos devuelve la lista entera de todos los diccionarios.

  2. grep -i 'computing' nos devuelve las líneas que contengan la palabra computing.

  3. cut -d' ' -fn nos devuelve el campo número n de la línea o líneas, donde cada campo esta separado del siguiente por un espacio.


Si unimos mediante una tubería la primera pieza con la segunda ---lo que hicimos el día pasado--- obtenemos una línea de la lista de todos los diccionarios, la referida al diccionario sobre computación. Esta línea (la salida de la tubería citada) se puede convertir a su vez en la entrada de la tercera pieza, precisamente por medio de otra tubería.

dict -D | grep -i 'computing' | cut -d' ' -f1

que nos devuelve el resultado esperado, o no ...:

[Vacío]

¡Fallo de HAL! ¿Cómo es esto posible? La cadena de tuberías es correcta. Todo parece bien diseñado y bien montado.

Si nuestro HAL fuese el HAL de la serie 9000 del film de Kubrik y nosotros el Dave Bowman de la película, HAL respondería, enojado por nuestras sospechas, con aquello de: "Ninguna computadora de la serie 9000 puede fallar. Este incidente sólo es atribuible a error humano." Si hubiésemos sido Dave Bowman no le hubiésemos creído y todo se habría ido al traste. Pero nosotros no somos Dave Bowman, porque también vimos la secuela de 2001, el film 2010, donde se constata que HAL tenía razón. Por tanto, debemos revisar con más cuidado lo que le hemos hecho digerir a nuestro HAL y asumir que el error es únicamente nuestro.

El error tiene que residir en la última tubería, puesto que la primera funciona perfectamente, como hemos visto al principio del artículo. Recordemos lo que nos devolvía esta primera tubería:

¶foldoc The Free On-line Dictionary of Computing (27 SEP 03)

Fijémonos en el signo incial, el ¶ que puse al principio para hacer visible el espacio con el que comienza la línea. El espacio es, justo, el delimitador que indicamos como separador de los distintos campos. Luego, este espacio, en apariencia insignificante para nosotros, es tan importante para HAL como el resto de letras y espacios de la línea. Para él funciona como el primer separador. Por eso nos ha devuelto el vacío, la nada: la palabra de 0 letras, por así decir, que hay antes de él.

Detectado el error, la situación es fácil de resolver si pedimos a HAL que nos devuelva el segundo campo de la línea y no el primero. [Existe otra forma más elegante de tratar la dificultad pero requiere el uso de otra tubería y otra orden y no conviene saturar al lector con tanta materia.]:

dict -D | grep -i 'computing' | cut -d' ' -f2

Que ---ahora, sí--- devuelve el resultado esperado:

foldoc

Diseñada la solución de la primera parte de nuestro tarea, queda la segunda, a saber, conseguir que la salida de la cadena de tuberías que acabamos de preparar se convierta en el argumento de la opción -d de dict.

En este tipo de situaciones no es posible el simple uso de una tubería, puesto que una tubería conecta la salida de una orden con la entrada de otra orden. Pero nuestro problema ahora es hacer que la salida de una orden se convierta, por así decir, en la entrada de un componente interno de la orden, y no de la orden considerada en total. En definitiva, nos vendría de perlas algún mecanismo, algún constructo en la lengua de HAL, que nos permitiese pedirle que sustituyese una orden (command substitution) por su resultado, algo así como un pronombre, si seguimos hablando en términos lingüísticos. Este mecanismo existe y su sintaxis es bien simple:

$(ORDEN)

Un ejemplo fácil:

echo 'El nombre de mi máquina es' $(hostname)

Tras la resolución de esta segunda parte del problema, sólo nos queda sintetizarla con la solución de la primera parte:

HAL, búsca en el diccionario cuyo nombre es éste (=el resultado de buscar 'computing' en la lista de todos los diccionarios y cortar en la línea resultante el nombre suyo) la palabra HAL

O mucho más simple ---la lengua de HAL empieza a ser más simple y comprensible que la nuestra:

dict -d $(dict -D | grep -i 'computing' | cut -d' ' -f2) HAL


A disfrutar de la respuesta.


Resumen:

  • Para resolver tareas con HAL es fundamental seguir una metodología determinada que consiste en analizar el problema, resolver cada parte del problema y sintetizar las soluciones parciales.

  • Aspecto central de la filosofía de diseño de HAL es que cada una de sus herramientas haga sólo una cosa, pero bien hecha.

  • La orden cut permite obtener de una o varias líneas los campos o columnas suyas que se deseen, siempre que cada campo está separado del siguiente por un mismo carácter delimitador.

  • Por medio de tuberías se pueden construir encadenamientos complejos de órdenes.

  • La sustitución de órdenes permite sustituir una orden por su resultado, allí donde tal resultado convenga en el interior de otra orden.

jueves, 29 de enero de 2009

HAL y dict en el laboratorio

dict nos ha sido presentado. Lo hemos conocido y estamos deseosos de charlar un rato con HAL para utilizar este nuevo recurso de su lengua.

Lo primero es pedirle a HAL que nos explique qué podemos esperar de dict. Utilizaremos el camino más corto y dejamos al lector parsimonioso que visite por su cuenta la página de manual dict(1).

dict --help

La respuesta contiene la descripción breve de 21 opciones, de las cuales seleccionamos solo dos, las que vamos a usar en nuestra conversación:


dict 1.10.11/rf on Linux 2.6.26-1-amd64
Copyright 1997-2002 Rickard E. Faith (faith@dict.org)
Copyright 2002-2007 Aleksey Cheusov (vle@gmx.net)

Usage: dict [options] [word]
Query a dictd server for the definition of a word

...
-d --database <dbname> select a database to search
-D --dbs show available databases
...


dict ---como ya sabemos--- busca en un diccionario la definición de una palabra. Desde el punto de vista de las máquinas cliente y servidor implicadas en el proceso, esto es lo mismo que decir que dict, el cliente, realiza una consulta a una base de datos existente en un servidor para dict. Es decir, "diccionario" y "base de datos en un servidor para dict" son sinónimos a todos los efectos. Dos expresiones que dicen lo mismo, si bien la primera la entendemos todos y la segunda sólo los especialistas en la materia.

O sea, que las opciones de dict que acabamos de ver se pueden igualmente expresar de la siguiente forma:


-d --database <diccionario> selecciona un diccionario en el que buscar
-D --dbs muestra los diccionarios disponibles


Si la consulta no se matiza con la opción -d, dict buscará la palabra en todos los diccionarios disponibles. Normalmente, no nos interesará este comportamiento. Lo habitual será especificar no sólo la palabra que buscamos, sino también el diccionario concreto en el que queremos buscarla. Lo cual significa que la orden más frecuente que daremos a HAL tendrá la forma:

dict -d <diccionario> [palabra]

Por otra parte ---y esto es sintácticamente novedoso--- la opción misma no es autosuficiente, requiere de su propio argumento (el diccionario en el que buscar). La estructura sintáctica sería pues:

ORDEN OPCIÓN ARGUMENTO_DE_LA_OPCIÓN ARGUMENTO_DE_LA_ORDEN

Para que quede más claro, construyamos un ejemplo de la orden anterior en nuestra lengua:

Busca en el diccionario Ingles-Español la palabra 'happy'

El análisis sintáctico sería el siguiente:

  • Busca (la orden)

  • en el diccionario (la opción)

  • Inglés-Español (el argumento de la opción)

  • la palabra 'happy' (el argumento de la orden)


Conviene retener esta posibilidad sintáctica, porque también es bastante frecuente en la lengua de HAL.

Es obvio tras la anterior consideración que antes de poder realizar una consulta en un diccionario tendremos que conocer el nombre del diccionario concreto que nos interesa, que será uno entre los muchos disponibles.

Precisamente, la opción -D nos da una lista de todos esos diccionarios:

dict -D

La respuesta es bastante larga. Parece que tendremos que leer cada entrada y localizar las que nos interesan. ¡Y así cada vez que decidamos cambiar de diccionario! ¡Menudo rollo! HAL, nos estás decepcionando.

¡Alto! Ya dijimos que es un deshonor para HAL dejarnos en la estacada, empantanados en tareas tediosas y repetitivas. HAL dispone de un recurso para evitar en este momento nuestro tedio y nuestros infundados reproches. Es un recurso nuevo. Es un recurso básico y fundamental. Es una de las razones por las que hay tantos fanáticos de HAL. Son ... ---¿lo sospechan?--- las tuberías (pipes).

Hay que detenerse todo lo necesario en este punto. Cuando nos habituemos al uso de las tuberías no habrá forma de pararnos. Haremos las delicias de nuestros amigos y dejaremos boquiabiertos a los incrédulos. Si pasamos de largo sin entender este artilugio, nos podemos despedir de dar el paso a la madurez en nuestras relaciones con HAL, nuestro enamoramiento habrá sido fugaz y no habrá lugar para el amor duradero.

Para empezar, describamos con cuidado nuestra actual tarea, la que acabamos de dejar sin resolver hace un instante: dict -D nos presenta una amplia lista de todos los diccionarios a los que puede consultar dict, pero nos interesan sólo aquellos relativos a una lengua en concreto, digamos, el español. Nuestro objetivo es conocer los nombres de los diccionarios bilingües de español para poder construir el argumento de la opción -d de dict.

Antes de seguir, preguntémonos si no podemos utilizar lo ya sabido para realizar esta tarea automáticamente. Si se recuerda el artículo HAL y mis ficheros ---léase de inmediato en caso de flojedad de memoria--- y se piensa un poco, se verá que la respuesta es afirmativa.

De igual manera que allí le pedimos a HAL que redirigiese la salida de la orden echo a un fichero, podemos redirigir la salida de dict -D a otro, llamémosle diccionarios:

dict -D >diccionarios

Y ahora podemos solicitar a HAL (con la orden grep) que busque dentro del fichero diccionarios, que acabamos de crear, las líneas que contengan la palabra "spanish". Pero antes de enviar la orden a HAL vamos a ser precavidos y matizarla para que HAL busque por la palabra "spanish" sin tener en cuenta si está en mayúsculas o minúsculas, es decir, para que busque "spanish", "Spanish", "SPANISH" o cualquier variante posible. A este fin sirve la opción -i de grep. Por tanto:

grep -i 'spanish' diccionarios

Que nos da el resultado apetecido:

eng-spa English-Spanish Freedict dictionary
spa-eng Spanish-English Freedict dictionary

El único problema de esta forma de proceder es que se crea un fichero provisional nuevo, diccionarios, que luego habrá que molestarse en eliminar ---por cierto esto se hace con la orden rm diccionarios. A ojos de HAL ello significa una carga onerosa para el usuario y, como tal, un procedimiento tedioso del que debe exonerarnos.

¿Cómo lo consigue? Pongámonos en lugar de HAL y tratemos de pensar como él. Para HAL un fichero no es más que una secuencia de bytes y un fichero de texto no es más que un flujo de caracteres, una secuencia de letras ---dicho con cierta imprecisión. Ahora bien, las órdenes que le introducimos y las respuestas que nos da tienen a todos los efectos prácticos el mismo estatuto que un fichero (flujos de texto). Preguntas, respuestas, ficheros son, desde este punto de vista, exactamente lo mismo para HAL, corrientes de datos que atraviesan a toda velocidad su territorio, pertrechado con ávidos estómagos electrónicos de todas las clases dispuestos a dar buena cuenta de ellas.

Pensemos, por ejemplo, en grep, que analizó el contenido del fichero diccionarios en busca de una palabra. Un fichero como diccionarios es un mero flujo de texto con el que alimentamos a grep para que lo procese como él sabe. ¿Por qué no hacer que grep consuma un flujo procedente de otra parte? No hay nada que se lo impida. A grep le da igual cuál sea su fuente. Es más, grep, por defecto, es decir, si no se le dan argumentos, la toma del propio dispositivo donde introducimos los datos (el dispositivo de entrada). Imaginemos este dispositivo como la cañería principal por la que entran los flujos. Esta cañería está habitualmente en manos de HAL ---en realidad de otro secuaz suyo, hasta ahora no presentado, que está continuamente recibiendo el caudal. El caso es que para dejar que grep se haga por un momento con el control de la cañería principal basta con no proporcionarle argumentos. Entonces el se adueñará de ella y empezará a devolver los resultados de su procesamiento, a medida que, línea a línea, vaya consumiendo los datos del flujo. Veámoslo un momento:

grep 'hola'

Después de pulsar Enter, alimentamos a grep enviándole líneas de texto:

Si eres grep
me devolverás una respuesta
cuando veas una línea
con la palabra hola
con la palabra hola # Esto lo devuelve grep
Adios grep
Ctrl+D

(La última línea Ctrl+D no se ve en pantalla, es lo que pulsamos nosotros ---las dos teclas a la vez--- para que la cañería vuelva a pasar a las manos de HAL).

Este experimento de alimentar a grep directamente desde la cañería principal no deja de ser un pasatiempo, pero nos viene bien para corroborar empíricamente lo que habíamos dicho, que la fuente de alimentación de grep no tiene que ser necesariamente un fichero.

De ahí surge una posibilidad feliz en extremo ---y, atención, ésta es la idea fundamental---: que la fuente de alimentación de grep sea el resultado de otra orden, que su alimento sea la salida de lo que otro súbdito de HAL ha procesado previamente. Para ello lo único que necesitaremos es un dispositivo de canalización, algo que nos sirva para canalizar el producto de un procesamiento hacia el conducto de entrada de grep.

Pues bien, este dispositivo de canalización es lo que llamamos una tubería o, simplemente, tubo (del inglés, pipe) y se representa mediante el signo |. La sintaxis en este caso es tan simple que casi da vergüenza ponerla por escrito:

ORDEN-1 | ORDEN-2

(donde la salida de la ORDEN-1 es canalizada y se convierte en la entrada de la ORDEN-2).

Sobra decir que la ORDEN-2 no tiene por qué ser grep y que infinidad de órdenes pueden verse sometidas al mismo tipo de canalización. Pero como estamos con grep y los diccionarios, volvamos al ejemplo que discutíamos antes y apliquémosle la nueva técnica.

En la mesa de laboratorio tenemos dos piezas: en primer lugar, una retorta que genera la lista completa de todos los diccionarios en los que dict puede consultar:

dict -D

En segundo lugar, un grep dispuesto a filtrar cualquier secuencia de texto que lo atraviese:

grep -i 'spanish'

Ahora conectamos con un tubo las dos piezas:

dict -D | grep -i 'spanish'

La salida de la primera orden (el flujo consistente en la lista completa de diccionarios) se convierte, en virtud de la canalización, en la entrada de la segunda (del filtro que bloquea el paso de toda línea del flujo que no contiene 'spanish'). Y la solución resultante, que se derrama en el recipiente de salida (la pantalla) es la misma de antes (la lista filtrada), pero sin pasos intermedios y sin pérdidas de tiempo:


eng-spa English-Spanish Freedict dictionary
spa-eng Spanish-English Freedict dictionary


Una vez conocido el nombre del diccionario bilingüe que nos interesa, tenemos ya el ingrediente que nos faltaba para construir completamente nuestra orden:

dict -d eng-spa bye

Que, naturalmente nos devuelve el ansiado licor:

1 definition found

From English-Spanish Freedict dictionary [eng-spa]:

bye [biː]
adiós
hastaluego, hastalavista



Resumen:

  • Para buscar una palabra en un diccionario concreto se usa la orden dict con el formato dict -d [diccionario] [palabra].

  • Las opciones de ciertas órdenes pueden requerir argumentos específicos, que han de escribirse justo después de la opción. Tal el es caso, por ejemplo, de la opción -d de dict.

  • La opción -i de grep hace que el patrón de búsqueda sea insensible a la escritura en mayúscula o minúscula de las letras que lo constituyen.

  • La orden rm elimina un fichero.

  • Una tubería (pipe) es un constructo central de la lengua de HAL que permite que la salida de una orden se convierta en la entrada de otra. Gracias a las tuberías la flexibilidad de HAL puede alcanzar límites insospechados.

miércoles, 28 de enero de 2009

HAL y dict

dict fue el paquete agraciado con el premio de poder ser a partir de ahora un ayudante más en el selecto grupo de colaboradores de HAL.

Pero, antes de proceder a su investidura, no está de más resumir el proceso completo de su selección. Se verá que las tareas que se llevaron a cabo para realizarla consumen bastante menos tiempo de lo que lleva leer y asimilar los tres artículos anteriores. Para completar el proceso, añadiré al final la única tarea no realizada todavía, la instalación propiamente dicha. [Destacaré en negrita la orden principal de cada paso]:

  1. Buscamos, sin éxito, órdenes relacionadas con el término 'diccionario':
        apropos dicitionary

  2. Buscamos paquetes relacionados con los términos 'diccionario' y 'línea de comandos'. La búsqueda se centró en las etiquetas de los paquetes:
        aptitude search '~Gdictionary ~Gcommandline'

  3. Procedimos a una criba manual del resultado obtenido, que guardamos en el fichero llamado 'candidatos', y obtuvimos información de los candidatos guardados en ese fichero [A diferencia del día pasado voy a suponer que la lista contenida en el fichero 'candidatos' consistió en la serie de los nombres de paquetes separados por espacios, que hubiese sido la forma lógica de esa lista, de no haber tenido que explicarla y presentarla en un navegador]:
        aptitude show  $(cat candidatos) | more

  4. Y el paso final, el que toca hoy hacer. Instalamos el paquete resultante de nuestra criba. Para efectuar esta operación tenemos que ser root [quien usa sudo en lugar de su, sustituya sudo por su -c en la orden siguiente y quite las comillas; quien usa su, lea la ayuda de su relativa a la opción -c]:
        su -c 'aptitude install dict'



Y ahí está dict, dispuesto a que empecemos a asignarle su tarea. Pero antes habrá que conocerlo en persona y saber de él lo suficiente. Cuando instalamos un paquete nuevo no sabemos de él más que lo que aptitude show nos dice, es decir, algo así como su curriculum. Pero de ahí a ponerlo a trabajar en el papel para el que fue instalado hay un trecho.

Lo más recomendable para trabar un conocimiento eficaz con un paquete nuevo es ir de inmediato a la ayuda incluida en el propio paquete. Sí, un paquete consta de varias cosas, aparte del programa o programas que agrupa, entre ellas está una ayuda inicial. Esta ayuda puede ser de dos tipos: en primer lugar, la que redacta la persona o personas que crearon el paquete (los mantenedores) y que suele versar sobre cuestiones específicas de nuestra distribución; en segundo lugar, la ayuda que el propio creador haya proporcionado y que el mantenedor del paquete incluirá dentro de él. En el caso de distribuciones basadas en Debian esta ayuda y otro tipo de documentación, que no vamos a comentar, se encuentra bajo el directorio
/usr/share/doc/[nombre_del_paquete].

Veamos pues que hay en el directorio correspondiente a dict. Para ello debemos pedirle a HAL algo que todavía no hemos hecho nunca, que nos dé una lista del contenido de ese directorio.

HAL, dame una lista del contenido de /usr/share/doc/dict

O, en breve,

lista /usr/share/doc/dict

Que en lengua de HAL se dice así:

ls /usr/share/doc/dict

No me gusta demasiado como sale en mi pantalla la respuesta. Así es que voy a matizar la solicitud inicial para que HAL me la presente con cada ítem en una línea distinta:

ls -1 /usr/share/doc/dict

El resultado de esta última orden es el siguiente:

changelog.Debian.gz
changelog.gz
copyright
examples
NEWS.Debian.gz
NEWS.gz
README.Debian.gz


Todavía no sé con exactitud si todo el contenido del directorio son ficheros o hay también subdirectorios u otras cosas. Le añadiré un matiz más a mi consulta anterior de modo que sepa también qué tipo de ítem es cada uno de los ingredientes del directorio:

ls -1 -F /usr/share/doc/dict

Lo que me devuelve:

changelog.Debian.gz
changelog.gz
copyright
examples/
NEWS.Debian.gz
NEWS.gz@
README.Debian.gz


Vaya. Han surgido dos nuevos signos. ¿Qué significan? El sentido de el caracter / es obvio, señala que examples es un directorio. El del carácter @ no es deducible sin leer la página de manual ls(1). Tras consultarla descubrimos que la @ indica que NEWS.gz es un enlace simbólico. Dejemos el tema de los enlaces simbólicos para otra ocasión y sigamos adelante.

Todos los ficheros "normales" que hay en /usr/share/doc/dict terminan con .gz. Sin entrar en detalles, este sufijo indica que se trata de ficheros comprimidos. Un fichero comprimido es el resultado de someter un fichero cualquiera a un proceso de compresión para reducir su tamaño. Por ejemplo, un fichero de audio se puede comprimir de varias maneras, una de ellas da como resultado los conocidos ficheros mp3. También se pueden comprimir ficheros de texto para que ocupen menos espacio en disco. Es el caso de los ficheros que nos ocupan.

Ahora bien, no podremos ver estos ficheros sin herramientas especiales. Por ejemplo, no nos valdrá la ya utilizada orden more para visualizar su contenido. O sí, veremos algo, pero se tratará de un galimatías. Órdenes como more (que, técnicamente, se denominan paginadores) disponen de variantes específicas para la visualización de ficheros comprimidos. En el caso de more la variante es zmore.

¡Vale! ¿Pero qué ficheros paginamos? ¿Contienen todos la ayuda sobre dict que estamos buscando?

No. Como ya dije el contenido del directorio /usr/share/doc/[paquete] puede constar de varias clases de información. Nosotros nos vamos a ceñir sólo a lo que nos interesa, la ayuda inicial. (Dejo que el lector curioso investigue por su cuenta en los ficheros que no comentaremos aquí). Un nombre de fichero típico para designar la ayuda previa es LEEME, o, en inglés, README. En el caso de dict tenemos un fichero con ese nombre, más el añadido '.Debian', lo que indica que es un fichero específico de nuestra distribución, creado por el mantenedor del paquete. Veamos qué nos quiere decir la persona que ha producido este paquete para nosotros, pidámosle a HAL que nos muestre el fichero comprimido README.Debian.gz:

zless README.Debian.gz

La salida ---que omito--- contiene bastante cosas que no sabemos de qué van. Esta es una situación típica. Nos habrá pasado, sin duda, al leer las páginas del manual. Es crucial ---lo repito, es crucial--- que no arrojemos la toalla en estas situaciones. Debemos seguir leyendo y tratando de entender lo que podamos, lo que esté a nuestro alcance. Sólo el contacto continuo con el lenguaje técnico va a permitirnos avanzar. El mundo extraño que al principio nos plantea se irá aclarando poco a poco con el tiempo. Así hemos empezado todos, incluidos los gurus. La gran diferencia entre el usuario zoquete y el amigo de HAL no tiene que ver con la inteligencia, sino con el carácter. La pereza, el pesimismo, el conformismo y cosas de ese estilo son la causa de muchos males y entre otros de la ineficacia y ramplonería en el uso de las computadoras. No caigas, lector, en los vicios de los bobalicones y aguanta el tipo, también cuando no entiendas nada.

Rescatemos un párrafo del fichero README.Debian.gz [lo vierto al castellano]:
El fichero de configuración por defecto hace que dict trate de acceder al servidor dictd en el host local. Si esto falla, dict intentará acceder a un servidor público en el sitio de Internet dict.org. Se debe estar conectado a Internet para poder acceder al servidor público; el cliente dict no establecerá de forma automática la conexión.


De este párrafo aprendemos lo siguiente:

  • dict funciona según lo establece un fichero de configuración. [Nada nuevo. Ya hablamos de los ficheros de configuración hace tiempo.]

  • dict funciona en modo cliente-servidor.

  • Si no tocamos el fichero de configuración, dict accederá primero al servidor local (dentro de nuestra máquina) y en caso contrario a un servidor remoto de Internet abierto al público.

  • Hay que estar conectado a Internet para poder acceder al servidor remoto. [Bastante natural]



Lo único oscuro de estas explicaciones tiene que ver con lo de cliente y servidor. Como se trata de un concepto capital de la ciencia informática, conviene comprender, al menos intuitivamente, de qué va el asunto.

Para poder leer esta página web que estamos leyendo ahora, nuestro navegador (el cliente web) ha tenido que pedírsela a la maquina donde la página reside. Nuestra solicitud ha atravesado multitud de máquinas y ha llegado finalmente a su destino. La máquina que aloja la página posee un encargado para atender a cualquier solicitud de este tipo. Fue este encargado (el servidor web) el que nos ha remitido la página de vuelta. Imaginemos que creamos un sitio web y lo alojamos en nuestra máquina. Cuando nuestro navegador quiere visitar ese sitio su solicitud será atendida por un encargado (un servidor web) instalado dentro de nuestra máquina misma. En este último caso no habrá necesidad de estar conectado a Internet, porque nuestra solicitud se gestionará dentro de nuestra máquina y no tendrá que atravesar máquinas externas para ser atendida.

Este tipo de arquitectura cliente-servidor es común a muchos servicios, además de la Web. Da igual que lo que se solicite sea una página web o una entrada de diccionario o cualquier otra cosa imaginable. En una arquitectura cliente-servidor una parte (el cliente) hace las veces del solicitante y la otra (el servidor) la del encargado de atender las solicitudes. Tanto cliente como servidor hablan el mismo idioma y se comportan siguiendo convenciones conocidas por ambos.

En el caso que nos ocupa el cliente es dict y el servidor dictd. El servidor puede ser local (puede estar en nuestra propia máquina) o puede ser remoto (estar en una máquina de la organización dict.org). Si dict no encuentra lo que busca en nuestra máquina ---porque nuestra máquina no contenga los diccionarios correspondientes, que hay que instalar aparte--- lo buscará en dict.org.

Hasta aquí está claro, y esto es lo que, por el momento, nos enseña el fichero README.Debian.gz sobre dict.

Como esta vez no vamos a modificar ningún fichero de configuración ni a instalar paquetes de diccionario para el servidor local dictd, confiamos en que nuestra consultas sobre artículos de diccionario sean resueltas por servidores remotos.

Pero aún nos queda conocer cómo realizar la consulta propiamente dicha, es decir, cómo pedirle a HAL que se valga de dict para realizar consultas en diccionarios remotos.

Ahí es donde empieza el camino conocido: la lectura de la página de manual de dict. Lo veremos el día próximo.


Resumen:

  • Un paquete está constituido por multitud de ficheros. Además de los programas propiamente dichos, las páginas de manual, etc., suele contener alguna clase de información básica sobre sí mismo. En los paquetes Debian esta información se encuentra bajo el directorio genérico /usr/share/doc/ y es un buen punto de partida para obtener información inicial sobre el paquete, más allá de la que proporciona aptitude show.

  • La orden ls permite listar el contenido de un directorio.

  • Un fichero comprimido es un fichero cualquiera sometido a un proceso de compresión para reducir su tamaño.

  • Existen variantes específicas de los paginadores habituales, que permiten visualizar ficheros de texto comprimidos. En el caso de more esta variante es zmore.

  • Un gurú es alguien que no tuvo miedo, pereza o desconfianza ante lo desconocido y que, a fuerza de ilusión, tesón y paciencia llegó a convertirse en un maestro.

  • La arquitectura cliente-servidor es omnipresente en las redes de computadoras. Consiste en una aplicación distribuida en dos partes, la parte cliente realiza solicitudes que la parte servidor responde. La comunicación entre cliente y servidor se realiza en base a una serie de convenciones y comportamientos tipificados conocidos por ambos.

  • La aplicación dict es un caso de arquitectura cliente-servidor.

martes, 27 de enero de 2009

Castings con HAL

El día pasado dimos inicio a una actividad que va a ser, sin duda, uno de las más frecuentes en nuestra vida con HAL, la gestión de paquetes. La ocasión la dio nuestro deseo de disponer de un diccionario bilingüe aquí mismo, en la consola. Con la ayuda de aptitude, HAL logró presentarnos una serie de candidatos posibles de entre la descomunal lista de paquetes disponibles. Podríamos haber tratado de refinar aún más la búsqueda con nuevos patrones de búsqueda u otras palabras clave. Sin embargo, como la lista no es demasiado larga, quizá sea hora de que asumamos nuestra responsabilidad, pongamos paz en la inquietud de los aspirantes y, como directores del cotarro, seleccionemos al protagonista de esta escena bilingüe en el gran drama haliano.

Todo este proceso de selección, que vamos a desgranar en un instante, puede efectuarse sin recurrir a los encadenamientos de órdenes que van a aparecer hoy. Estos encadenamientos se pueden considerar moderadamente avanzados. Es probable, pues, que el principiante se acobarde ante ellos o que caiga víctima de un vértigo y una angustia irrefrenables.

No hay que temer estas sensaciones. Son naturales y sólo se desvanecen cuando el trato con HAL se transforma de superficial y ocasional contacto en relación profunda. El lector de estas conversaciones llegará en poco tiempo a esa intensidad comunicativa, si tal es su deseo. Sólo que ahora es pronto para plantar cara a los aspectos a primera vista más intrincados de la lengua de HAL.

¿Por qué, entonces, hacerlos entrar ya en escena? ¿No habría sido mejor esperar?

La razón es didáctica. Hasta ahora casi todo recurso de la lengua de HAL se ha explicado justo en el momento de su aparición. Sin embargo, el aprendizaje de cualquier lengua extraña sigue derroteros por completo diferentes. El aprendiz está expuesto desde el principio a la totalidad de la lengua, que se le manifiesta como un enigma inabordable sobre el que sólo poco a poco van surgiendo zonas de luz e inteligibilidad. Sin querer llegar a tales extremos, me ha parecido conveniente procurar hoy un tipo de impregnación semejante a ésta bien conocida, precisamente en un asunto muy significativo de la lengua de HAL. El presupuesto es que el contacto semiconsciente con ciertas estructuras lingüísticas puede servir de preparación para un tratamiento sistemático posterior.

A pesar de lo dicho, el lector que encuentre en la experiencia motivo más de repugnancia que de expectación, puede perfectamente dejar de leer en el momento que lo desee y continuar con los artículos siguientes. Nada esencial se pierde por hacerlo.

Hecha la advertencia, volvamos por donde lo dejamos: al proceso de selección del paquete para diccionarios.

El día pasado presenté la lista inicial que nos dio HAL. La voy a mostrar de nuevo. Pero para que los candidatos a protagonistas de nuestra próxima escena no se quejen, eliminaré de ella los paquetes ya instalados e incluiré también las descripciones breves de todos los demás. Tengo que formatear la lista de un modo distinto de como por defecto nos la da aptitude, si quiero que quepa en la pantalla. Pero no lo haré a mano ---líbreme el cielo de esa carga inútil. HAL, que es un maestro en la manipulación de texto, lo hace por mí, aunque a veces resulte extraña la forma de pedírselo:
aptitude --disable-columns -F "%c:%p:%d" search '~Gdictionary ~Gcommandline' \
| grep -v ^i | awk -F: '{printf "%s:\n%s\n\n", $2, $3}' | tee candidatos


Esta larga retahíla produce otra vez el casting de aspirantes, pero con un nuevo formato:

aiksaurus:
an English-language thesaurus (utility)

anthy:
Método de introducción de japonés

anthy-el:
input method for Japanese - elisp frontend

brazilian-conjugate:
Brazilian Portuguese verb conjugator

chasen:
a Japanese Morphological Analysis System

chasen-dictutils:
a Japanese Morphological Analysis System - utilities for dictionary

crack:
Programa para adivinar contraseñas

crack-md5:
Programa para adivinar contraseñas

cracklib-runtime:
runtime support for password checker library cracklib2

dict:
Cliente de diccionario

dictem:
Dict client for emacs

dictfmt:
Utilidad para dar formato a un archivo para que el servidor de dictd pueda usarlo

dictzip:
Compression utility for dictionary databases

duali:
The Arabic Spell Checker

eblook:
electronic dictionary search command using EB Library

epwutil:
Varias utilidades para EB(Libro Eléctrico)/EPWING

glosstex:
prepare glossaries and lists of acronyms

gnuvd:
Query the online Dutch Van Dale dictionary

gramadoir:
Irish language grammar checker (integration scripts)

hspell:
corrector ortográfico y analizador morfológico de hebreo

i2e:
English-Spanish translation dictionary

link-grammar:
Intérprete de la gramática de enlace de la Universidad Carnegie Mellon para Inglés

lookup:
interactive utility to search text files quickly

makedic:
A dictionary compiler for KDrill

mecab-utils:
Support programs of Mecab

rmligs-german:
Elimina ligaduras usadas incorrectamente en documentos LaTeX

sary:
Una biblioteca de vector de sufijos (programa)

sdcv:
StarDict Console Version

skktools:
Herramientas de mantenimiento para diccionarios de SKK

spell:
GNU Spell, a clone of Unix `spell'

spellutils:
Utilidades para la corrección ortográfica

sufary:
Herramientas de búsqueda de texto completo usando un vector de sufijos

thescoder:
compiler for OpenOffice 1.x thesaurus files

translate:
traduce palabras de inglés a alemán o viceversa

xjdic:
Japanese-English dictionary search program


Un repaso rápido por las cartas de presentación de los candidatos (las descripciones breves de los paquetes), nos permite descartar unas cuantas entradas (las relativas a otras lenguas, los analizadores gramaticales u ortográficos, los programas de descubrimiento de contraseñas, etc.), y concentrarnos en unas pocas, incluidas las que ni siquiera entendemos de qué van.

O sea, que tendríamos que editar la lista anterior y suprimir todas las entradas referentes a los excluidos en esta primera criba. Pero no apetece hacerlo a mano. Es una deshonor para HAL que insistamos en los trabajos manuales estando él ahí. Dejémosle que lo haga él por nosotros [He adaptado ligeramente la orden respecto de lo que sería en realidad para que quepa aquí]:

grep -E -v \
-e 'aiksaurus|anthy|anthy-el|brazilian-conjugate|chasen|chasen-dictutils' \
-e 'crack|crack-md5|cracklib-runtime|dictzip|duali|glosstex|gnuvd|gramadoir' \
-e 'hspell|link-grammar|lookup|rmligs-german|sary|spell' \
-e 'spellutils|sufary|thescoder|translate|xjdic' \
candidatos \
| grep :$ -A1 | tee candidatos_firmes


Y HAL nos da la siguiente lista remozada:


dict:
Cliente de diccionario

dictem:
Dict client for emacs

dictfmt:
Utilidad para dar formato a un archivo para que el servidor de dictd pueda usarlo

eblook:
electronic dictionary search command using EB Library

epwutil:
Varias utilidades para EB(Libro Eléctrico)/EPWING

i2e:
English-Spanish translation dictionary

makedic:
A dictionary compiler for KDrill

mecab-utils:
Support programs of Mecab

sdcv:
StarDict Console Version

skktools:
Herramientas de mantenimiento para diccionarios de SKK


La lista es cada vez más corta, pero necesitaremos una información más detallada sobre cada paquete para poder tomar una determinación fiable. Ya sabemos cómo pedir esa información, con aptitude show.
aptitude show  $( grep :$ candidatos_firmes | sed 's/://' | tr '\n' ' ' ) | more


Y HAL nos presenta los correspondientes informes, que omito, dada la longitud del resultado.

Después de revisarlos, procedemos a un nuevo descarte. [Los procedimientos para la obtención de la lista definitiva son semejantes a los anteriormente especificados.] El resultado final de esta selección definitiva es el siguiente:

dict:
Cliente de diccionario

i2e:
English-Spanish translation dictionary


El papel protagonista se lo llevará, en nuestro caso, dict, porque también se le debe permitir al director dar rienda suelta a su subjetividad, si no, no sería el dire. Ya veremos el día que viene que pueda aportar dict a nuestra consola.


Fin del casting y meditaciones del realizador:
Nos ha llevado un buen trecho adoptar una decisión final. Es posible que, por el camino, hayamos dejado algún paquete sin revisar, ya fuera porque nuestras búsquedas fallaron en algún punto ---ningún tiro a la diana acierta siempre y por completo--- o ya porque los desarrolladores de los paquetes no caracterizaron con suficiente minuciosidad sus productos o nosotros no entendimos bien sus caracterizaciones. Por supuesto, siempre queda el camino del "listillo", la recomendación de un poderoso. En el mundo del software libre, por suerte, no suele darse fenómenos de arribismo descarado, son muchos ojos los que ven y las componendas prácticamente no existen, por eso la recomendación suele ser también un buen punto de partida. No obstante, nunca está de más proceder con nuestras propias herramientas ---las de HAL--- para descubrir los paquetes que nos interesen. Esta sesión y la anterior han tratado de mostrar un ejemplo práctico de cómo hacerlo.

domingo, 25 de enero de 2009

Los paquetes de HAL

En la entrada pasada nos quedamos con la miel en los labios. La necesidad de un diccionario bilingüe nos llevó a descubrir que tenemos que instalar un paquete nuevo en nuestro HAL. Conseguimos saber, además, que HAL cuenta para la gestión de paquetes con ayudantes especializados, de entre los cuales aptitude destaca como uno de los candidatos más firmes. Pero no sabemos nada de aptitude, más allá de su supuesto "talento" (que es lo que el término inglés aptitude significa en castellano).

Hoy vamos a aprender, por fin, lo que este talentoso ayudante puede hacer por HAL y alguna de las órdenes fundamentales que entiende.

No viene mal empezar con una breve consideración sobre su sorprendente nombre. En realidad, es chocante que una, entre tantísimas herramientas excelentes, tenga la desfachatez de acaparar para sí tan presuntuoso calificativo. Sin embargo, las sospechas sobre su inmoderado afán de protagonismo se desvanecen si atendemos a su verdadero origen. Y la verdad es que el nombre aptitude no es otra cosa que un juego de palabras con la sigla apt. Apt es una abreviatura de advanced package tool (herramienta avanzada de paquetes) y es, además, el nombre del precursor de aptitude en la gestión de paquetes de distribuciones basadas en Debian. De hecho, apt se sigue usando hoy en día para esta tarea, si bien aptitude, al añadir o simplificar funcionalidades que ya poseía apt, es, con frecuencia, la opción recomendada por los expertos.

Conviene extraer de esta curiosa consideración una pequeña idea. Ya hemos comprobado el abundante uso de abreviaturas o siglas en la lengua de HAL. No deberá sorprendernos a partir de ahora encontrar también términos que proceden de juegos de palabras. Y es que, contra lo que parece, la lengua de HAL está llena de guiños, de ironías y, en último término, de sentido del humor.

Fin de los devaneos y entrada en materia.

¿Qué puede hacer este gracioso aptitude por HAL y por nosotros? Puede hacer bastantes cosas, comunes, por cierto, a todos los gestores de paquetes. Pero lo que a nosotros nos interesa ahora es que haga, al menos, estas tres:

  • Buscar entre los paquetes disponibles en los almacenes de paquetes aquellos que, según el caso, nos interesan.

  • Mostrar información sobre los candidatos seleccionados en esa búsqueda para definir mejor nuestra decisión.

  • Instalar el paquete o paquetes que le indiquemos.



Las órdenes que entiende aptitude para ejecutar estos tres cometidos no podían ser más intuitivas: search (= buscar), show (= mostrar) e install (= instalar).

¿Y la sintaxis? La sintaxis varía ligeramente dependiendo de la orden que aptitude reciba. Sin pretender ser exhaustivo, lo más sencillo es asimilar unos cuantos ejemplos básicos.

aptitude install moreutils

Instala el paquete cuyo nombre es moreutils.

aptitude show moreutils

Muestra información sobre el paquete cuyo nombre es moreutils.

aptitude search utils

Busca paquetes relacionados con la palabra utils. (El segundo argumento es una expresión o patrón de búsqueda).


Los dos primeros ejemplos no requieren mayor explicación, salvo la de que puede haber más argumentos, cada uno de los cuales sería, de nuevo, un nombre de paquete que se quiere instalar o sobre el se solicita información; p. e., aptitude show kde gnome mostraría información sobre los paquetes kde y gnome. El tercer ejemplo sí que exige un estudio aparte.

¡Pues, vaya!, la búsqueda de paquetes, que es lo primero que evidentemente hay que dominar ---porque si no, a ver cómo vamos a conocer el nombre del paquete o paquetes que nos conciernen---, ¡resulta que es lo más raro! ¿Qué es eso de un patrón de búsqueda? En el ejemplo propuesto no parece nada complicado, utils es una palabra como otra cualquiera. ¿Por qué calificar esa palabra con el enrevesado apodo de patrón de búsqueda? ¿O es que ese segundo argumento para
aptitude search puede ser algo diferente de una palabra pura y simple?

Efectivamente, puede ser algo más. En realidad, puede ser mucho más. No es práctico ver todo lo que puede ser ---sería para volvernos locos---, es mejor ceñirnos a unos pocas posibilidades, justamente las que nos van a resultar útiles para obtener nuestro ansiado diccionario.

Por consiguiente, abandonemos las generalidades y pasemos al caso práctico. Sólo entonces, veremos con claridad la cuestión de los patrones de búsqueda y su pertinencia.

Vamos a ello.

HAL, dile a aptitude que me busque un diccionario

que, como acabamos de ver, se expresaría, en principio, de este modo:

aptitude search dictionary

La respuesta de mi HAL es la siguiente [presento sólo las 10 primeras líneas de un total de 59 ---algún día explicaré cómo las he contado, porque no lo he hecho con la cuenta de la vieja]:

v aspell-dictionary -
v aspell6a-dictionary -
v dictd-dictionary -
p dictionary-el - cliente de diccionario para Emacs
p dictionaryreader.app - Dict client for GNUstep
v hunspell-dictionary -
v hunspell-dictionary-ar -
v hunspell-dictionary-da -
v hunspell-dictionary-de -
v hunspell-dictionary-en -


Es digno de mención el hecho de que pedir a aptitude que busque, por ejemplo, algo sobre diccionarios es básicamente lo mismo que hacíamos mediante la orden apropos cuando pedíamos a HAL que buscase algo. La diferencia reside en el ámbito de aplicación de la búsqueda y en el objeto buscado. Mientras que con apropos buscamos dentro del propio HAL ciertas órdenes, con aptitude search buscamos dentro de los almacenes de paquetes residentes en Internet ciertos paquetes. Un proceso, en consecuencia, bastante natural es buscar primero (con apropos) en lo que tengo más cerca de mí y, si no lo encuentro, buscarlo en el exterior (con aptitude search). Lo hace todo hijo de vecino, primero busca el chocolate en la nevera, y si no lo encuentra ---mala suerte--- se tiene que ir a la tienda a por él.

No es, pues, mera coincidencia que el resultado de ejecutar ambas órdenes comparta un cierto aire de familia. Veamos como ejemplo, una línea cualquiera de la respuesta de apropos dictionary y aptitude search dictionary, respectivamente:

apropos:

remove-default-ispell (8) - remove default ispell dictionary

aptitude:

p   dictionaryreader.app  - Dict client for GNUstep



La respuesta a apropos consta del nombre de una orden ---aquí, remove-default-ispell--- y de un resumen de su descripción; la correspondiente a aptitude consta del nombre de un paquete ---dictionaryreader.app--- y de un resumen de su descripción. Sólo hay dos diferencias: el número de sección en la página de manual, asociado a la orden, que falta en el paquete, puesto que un paquete no tiene páginas de manual, y el prefijo que aparece delante del paquete ---en el ejemplo, p---, que no existe en el caso de la orden.

¿Cuál es el significado de este prefijo al nombre de un paquete en la respuesta de aptitude? Se trata, simplemente, de una señal ---técnicamente se llama bandera (flag)---, que indica cuál es el estado actual del paquete. Normalmente sólo veremos tres o cuatro de estos prefijos ---en caso contrario, habrá algo raro en la instalación. En nuestra situación actual, con la instalación de la distribución tal como viene de fábrica, nos podemos con encontrar uno de estos tres:

  • i: el paquete está instalado. [Es muy común encontrar el prefijo i A, que significa que el paquete fue instalado automáticamente, sin intervención del usuario.]

  • p: el paquete no está instalado, no hay rastro de él en el sistema o, lo que es lo mismo, el sistema está completamente limpio (purged) de él.

  • v: el paquete es un paquete virtual. Un paquete virtual es uno que no existe realmente, se trata simplemente de un mero nombre que el sistema de paquetes puede usar para fines internos. De momento, nos olvidaremos de estos "paquetes" virtuales.



Con toda esta información podemos entender exhaustivamente la respuesta que anteriormente dio HAL a nuestra pregunta sobre los paquetes relacionados con el diccionario. La vuelvo a reproducir para facilitar la lectura:

v aspell-dictionary -
v aspell6a-dictionary -
v dictd-dictionary -
p dictionary-el - cliente de diccionario para Emacs
p dictionaryreader.app - Dict client for GNUstep
v hunspell-dictionary -
v hunspell-dictionary-ar -
v hunspell-dictionary-da -
v hunspell-dictionary-de -
v hunspell-dictionary-en -


Si nos fijamos en la respuesta completa ---aquí están reproducidas únicamente las diez primeras líneas---, notaremos una curiosa coincidencia, a saber, todos los nombres de los paquetes contienen la palabra que dimos como patrón de búsqueda a la orden aptitude search, esto es, la palabra dictionary. De ahí podemos deducir que si el patrón de búsqueda es una palabra pura y simple, aptitude va a buscar exclusivamente en el nombre de los paquetes. No es buena cosa o, al menos, no es suficiente, porque, si el nombre del paquete no contiene la palabra que nos interesa, no aparecerá entre las respuestas posibles. Se ve que apropos era más inteligente que aptitude, puesto que buscaba en las descripciones, donde es más probable acertar con lo que buscamos. No parece que aptitude tenga tanto talento como pretende.

Pobre aptitude, no le colguemos el sambenito de fanfarrón sin antes conocerle a fondo. aptitude puede hacer lo que queremos y más, sólo que hay que aprenderse un par de patrones de búsqueda.

Para que aptitude busque dentro de las descripciones de los paquetes el patrón adecuado es:

'~dtérmino_de_búsqueda'

Las comillas son convenientes, como siempre que introducimos esta clase de patrones. Aquí el signo de la tilde señala el comienzo del patrón de búsqueda. La letra siguiente es una abreviatura del tipo de búsqueda que se va a efectuar. En este caso, la d indica que se va a buscar dentro de las descripciones de los paquetes. Lo que se va a buscar es lo que viene a continuación. Asi, por ejemplo, si queremos buscar por "stupid" en las descripciones de los paquetes, el patrón de búsqueda sería:

'~dstupid'

Y, ojo, que salen varios resultados ;-)

Existe también una forma más larga de precisar el patrón de búsqueda. Quizá haya gente que la prefiera, por ser más clara y porque le recuerde el tipo de URLs que salen cuando se hacen búsquedas sobre bases de datos en un navegador:

'?description(stupid)'

Probemos ahora un patrón de búsqueda semejante para lo de nuestro diccionario:

aptitude search '~ddictionary'

¡Brutal!, HAL me devuelve nada menos que 271 paquetes. ¿Cuántos le devuelve al lector?

Está visto que hemos ido mucho más al grano, pero como contrapartida
hemos obtenido demasiadas respuestas. Debemos buscar otro procedimiento. Pero ¿cuál?

Si aptitude search acepta un patrón de búsqueda que le hace buscar dentro de las descripciones de los paquetes, tiene que haber otros patrones de búsqueda y, quizá, también otros lugares donde buscar, aparte del nombre y la descripción del paquete, ¿Hay un lugar donde el dardo de nuestra búsqueda se oriente hacia su blanco de un modo más certero?

Lo hay, en efecto. Ese lugar son las etiquetas (tags) o marcas que algunos usuarios y los propios creadores de las paquetes les adjuntan para caracterizarlos de un modo preciso. Aunque la categorización de los paquetes, como tarea humana que es, no es una obra acabada, una buena parte de los paquetes está etiquetada y bien etiquetada, de modo que podemos confiar en que buscar dentro de las etiquetas nos va a dar resultados fiables.

Para poder realizar este tipo de búsqueda especializada es necesario tener instalado el paquete debtags. Es probable que ya esté instalado ---con lo dicho hoy, el lector debería ser capaz de saber si lo está o no. En caso contrario, bastará con decirle a HAL que llame a aptitude para que lo haga de inmediato. [Eso sí, habrá que ponerse el disfraz de superusuario para que HAL nos permita efectuar esta operación]:

aptitude install debtags

Antes de continuar vamos a aliviar la comezón del lector. Se habla de etiquetas o marcas de paquetes, pero no tenemos ni idea de qué aspecto tienen. Veámoslo con nuestros propios ojos. Escoge, lector, cualquier paquete y mira las líneas finales del informe que te da de él aptitude. Veamos, por ejemplo, las marcas del propio paquete debtags:

aptitude show debtags

Las líneas finales son las siguientes:

Marcas: devel::buildtools, implemented-in::c++, interface::commandline,
role::program, scope::application, suite::debian, use::searching,
works-with::software:package


¡Bonito! El significado es el siguiente: los nombres de las facetas, esto es, los aspectos o puntos de vista desde los que vemos el paquete, vienen antes de los :: ; detrás, aparece el valor o etiqueta para ese paquete dentro de esa faceta. Así, por ejemplo, use::searching quiere decir que el paquete que estamos categorizando, visto desde la perspectiva de su utilidad es un paquete de búsqueda, o en breve, que el paquete sirve para buscar cosas. Como se puede colegir, esta forma de categorización es muy parecida, en esencia, a la que lleva a cabo el bibliotecario cuando etiqueta un libro.

No hace falta detenerse excesivamente en las etiquetas, sus tipos y las palabras claves para describirlas. Es suficiente con saber que están ahí y que podemos buscar dentro de ellas. Quizá sí merezca la pena comentar que los futuros desarrollos de estos sistemas de etiquetas para paquetes Debian harán seguramente más sencilla su integración con gestores de paquetes como aptitude.

Volviendo al asunto que nos ocupa, lo que a nosotros nos interesa buscar son diccionarios y, particularmente, diccionarios que funcionen desde la interfaz con la que hablamos con HAL, o sea, la consola y, más exactamente, desde el lugar donde tecleamos nuestras órdenes, que se denomina también la línea de comandos (commandline).

Lo único que queda por saber es el patrón de búsqueda estipulado para que aptitude sepa que la búsqueda debe efectuarse dentro de las etiquetas de los paquetes. Este patrón tiene esta forma:

'~Gtérmino_de_búsqueda'

Compongamos, pues, la orden para HAL:

HAL, haz que aptitude busque 'diccionario' y 'línea de comandos' en las etiquetas de los paquetes.

que debería decirse [adviértase el doble patrón]:

aptitude search '~Gdictionary ~Gcommandline'

o, en versión larga:

aptitude search '?tag(dictionary) ?tag(commandline)'

No me resisto a reproducir la lista completa, que ha quedado reducida a 36 líneas. [Suprimo de la salida las descripciones de los paquetes, porque no caben aquí]:


p aiksaurus
p anthy
p anthy-el
p brazilian-conjugate
p chasen
p chasen-dictutils
p crack
p crack-md5
p cracklib-runtime
p dict
p dictem
p dictfmt
p dictzip
p duali
p eblook
p epwutil
p glosstex
p gnuvd
p gramadoir
p hspell
p i2e
i libenchant1c2a
p link-grammar
p lookup
p makedic
p mecab-utils
p rmligs-german
p sary
p sdcv
p skktools
p spell
p spellutils
p sufary
p thescoder
p translate
p xjdic


Se trata, sin duda, de un buena selección, sobre todo si consideramos que, sin contar con los paquetes virtuales, aptitude dirigió su búsqueda sobre la friolera de 23.002 paquetes. Un buen punto de partida, desde el que continuar el día que viene.


Y, por fin, tras esta largo merodeo por el fantástico mundo de los gestión de paquetes Debian, el consabido resumen:

  • La lengua de HAL es proclive a los juegos de palabras.

  • aptitude admite diversas órdenes. Alguna de las más frecuentes son search, show e install.

  • aptitude search es comparable a una consulta apropos efectuada sobre almacenes remotos de paquetes, pero mucho más versátil.

  • Si no se especifica ningún patrón de búsqueda, aptitude search buscará por defecto en los nombres de los paquetes.

  • Patrones de búsqueda interesantes para aptitude son los que empiezan con ~d, que busca en las descripciones de los paquetes y con ~G, que busca en las etiquetas de los paquetes.

  • Los paquetes de Debian están etiquetados. Este sistema de etiquetas categoriza el paquete de una forma muy precisa y es la infraestructura ideal para localizar los paquetes que nos interesan.

sábado, 24 de enero de 2009

HAL y los diccionarios

El lector atento y educado ---lo demuestra el que no haya rechistado todavía--- habrá caído en la cuenta de una laguna en la adaptación de HAL a nuestra lengua. Incluso con las configuraciones realizadas, de vez en cuando siguen apareciendo mensajes breves o hasta páginas enteras de manual en inglés. Y seguirían apareciendo aun instalando paquetes ---se verá enseguida qué es eso de un paquete y cómo se instala--- como manpages-es-extra, que contiene páginas de manual traducidas a nuestro idioma y no instaladas por defecto.

A pesar de las triquiñuelas del autor para evitar entrar en el asunto durante las sesiones precedentes, llega el momento de decir la verdad. Los mensajes de HAL no están traducidos en su totalidad. La razón es sencilla. Las traducciones son obra de un grupo no muy numeroso de voluntarios que todavía no han culminado su trabajo, a pesar de haber dedicado infinitas horas al tema.

¿Qué hacer entonces? La primera recomendación para aquellos diestros en nuestra lengua y el inglés es colaborar en la traducción. Al fin y el cabo, HAL no es sino una work in progress, fruto de una colaboración, en la mayoría de los casos desinteresada, de hombres y mujeres de todas las regiones del mundo, edades y profesiones.

Los principiantes no podrán, sin embargo, asumir una tarea de esta envergadura y tendrán que acostumbrarse a luchar en ocasiones con el inglés. Alguna ayuda como un diccionario bilingüe podría ser eficaz en tales casos.

HAL no es capaz todavía de traducir adecuadamente textos enteros por sí mismo y sin intervención humana. Pero, ¿podemos pedirle que nos traduzca palabras?

Para resolver esta duda, vamos a dar ---cómo no--- un breve rodeo.

La lengua de HAL no es algo que forma parte de su ser como la pata de una mesa respecto de su mesa. HAL es una máquina programable. Lo cual significa, sin duda, muchas cosas. Significa, entre otras, que HAL, tal cual sale de la fábrica, es una mente prácticamente vacía, que sólo sabe hacer cuentas elementales y unas pocas cosas nimias más. Que pueda hablar su lengua, tal como la habla, y que responda con la sabiduría que lo hace se lo debemos a un grupo numeroso de individuos que se dedican a programarlo, a introducirle secuencias de texto, más o menos incomprensibles para la mayoría, llamadas programas. Los programas que constituyen a HAL se organizan en un entramado muy complejo de capas superpuestas que dependen unas de otras y que hacen posible que nosotros, sus contertulios, nos encontremos con la maravilla y el misterio de su inteligencia.

Pues bien, cuando instalamos una determinada distribución, la mente de HAL se ve nutrida por un buen número de tales programas, aquellos que los arquitectos de toda distribución en general y de la nuestra en particular consideran que son los básicos para que HAL se comporte con inteligencia y versatilidad suficientes. Tanto estos programas básicos como el resto de programas disponibles se agrupan en conjuntos de programas, relacionados por sus propósitos comunes o sus interdependencias, denominados paquetes. Empaquetar programas es una estrategia que las distribuciones siguen con el fin de facilitar la gestión de la ingente cantidad de programas existente.

En definitiva, las preguntas y consultas que HAL entiende a priori y la forma que tiene de responder a ellas son consecuencia de los paquetes que nuestra distribución ha considerado básicos.

Ahora bien, en algún momento de nuestras charlas con HAL puede suceder que los paquetes básicos no sean suficientes para cumplir nuestros propósitos. Dicho de otro modo, pueden darse situaciones en las que HAL no tenga conocimiento (no esté programado) para recibir cierto tipo de órdenes. Es entonces cuando nosotros mismos tendremos que tomar la iniciativa y alimentar a HAL con nuevos paquetes, instalar en su mente nuevos campos semánticos (nuevas órdenes) y formas de comportamiento relacionados con tales campos.

¿Pero cómo descubrimos que ha llegado el momento de instalar un paquete nuevo? Normalmente, y si no nos lo ha soplado ningún amigo, el proceso típico que conduce a tal conclusión es el siguiente:

  1. Deseamos hacer algo en concreto, pero desconocemos la orden u órdenes adecuadas que habría que dar a HAL para conseguirlo.

  2. Pedimos ayuda a HAL con la orden apropos [o cualquier otra semejante, aquí no explicada].

  3. Echamos un vistazo a las páginas de manual correspondientes sobre los posibles candidatos, si los hay.

  4. Ni apropos ni man nos informan de nada que sirva para cumplir nuestro objetivo.

  5. Ergo: es probable que tengamos que instalar un paquete nuevo.


Con todo este bagaje previo podemos retomar el hilo principal de la sesión de hoy.

Dejamos pendiente una pregunta: ¿es posible contar con HAL para que haga las veces de un diccionario, y, en especial, de un diccionario bilingüe?

Como no conocemos ninguna orden en este sentido, lo lógico es pedir a HAL que nos diga las órdenes que hay disponibles sobre el tema, si es que hay alguna. Podríamos probar, por ejemplo, con algo como:

apropos dictionary

o, quizá,

apropos dict

El lector seguramente se encontrará con varios candidatos. Si consulta someramente las páginas de manual de cada uno de ellos llegará tal vez a la conclusión de que hay herramientas de corrección ortográfica como ispell, pero no diccionarios propiamente dichos. Puede suceder, incluso, que encuentre tales diccionarios, pero que se trate de aplicaciones que se ejecutan dentro de un entorno de escritorio gráfico y no programas de consola, que es lo que estamos buscando. Con toda probabilidad parece que ha llegado el momento de instalar un nuevo paquete.

Seguro que HAL dispone de algún ayudante para este tipo de tarea, uno que se dedique a la gestión de nuestros paquetes. No sabemos cuál es el nombre de ese ayudante, así es que, como de costumbre, se lo preguntaremos a HAL. En concreto, le preguntaremos a ver qué sabe en relación con los gestores de paquetes [Asumo, a partir de ahora, que nuestra distribución es Debian o está basada en Debian, como Ubuntu. Los gestores de paquetes pueden ser diferentes según la distribución]:

apropos 'package manager'

Nótese que el argumento de apropos está formado por más de una palabra. En este caso ---y, en general, cuando el argumento de una orden contiene espacios---, habrá que evitar que HAL los interprete como caracteres con un significado sintáctico especial, cosa que hará, si no se le indica lo contrario. La forma convencional de indicárselo es entrecomillar el grupo de palabras de los que consta el argumento. De este modo, y en el caso que nos ocupa, HAL entenderá que el único argumento de apropos es un grupo de dos palabras. De no haberlas entrecomillado, HAL interpretaría la primera palabra como el primer argumento de apropos y la segunda como el segundo argumento.

La respuesta de HAL es la siguiente:

aptitude (8) - high-level interface to the package manager
dpkg (1) - package manager for Debian


Ya en la simple descripción que devuelve apropos, salta a la vista una curiosa diferencia: dpkg se define como un gestor de paquetes sin más matización, mientras que aptitude se define como una interfaz de alto nivel para un gestor de paquetes. Merece la pena detenerse un momento en esta diferencia.

Es frecuente el uso de la palabra interfaz en los textos sobre computadoras. Podemos ceñirnos a una de sus posibles acepciones, muy frecuente en tales textos, de acuerdo con la cual la interfaz de una cosa sería algo así como esa su cara amigable, la que la cosa nos proporciona para comunicarnos con ella. Es decir, que la cosa en cuestión tiene, en realidad, una cara hosca, dura, desagradable, etc. que debe ocultarnos, si no quiere que salgamos aterrorizados ante su visión. Si la interfaz es de alto nivel, la cara es la más agradable posible; si es de bajo nivel, probablemente veamos todavía en ella huellas de lo terrible subyacente. Un hacker es alguien que no se asusta ante la cosa misma, todo lo contrario, disfruta con ella; un usuario no puede, ni debe, mirar cara a cara la realidad en sí y requiere de una interfaz para soportarla.

Dicho esto, y como usuarios que somos, no podemos albergar dudas sobre la pertinencia de aptitude para nuestra tarea.

Si leyésemos la página de manual correspondiente a aptitude, podríamos entender qué hace este ayudante de HAL y cómo hablar con él. Puesto que es realmente larga y compleja me tomaré la libertad de evitar al lector el esfuerzo. Prometa, sin embargo, que lo hará cuando se considere todo un hacker, entonces podrá asimilarla en su totalidad en menos de una hora. El autor ---dicho sea como acicate al lector--- no se considera un hacker, pues ha tardado semanas en asimilar páginas de esta envergadura y, además, sólo ha llegado a conseguirlo parcialmente. Debe de ser que es un poco duro de mollera.

Y como es flojo de testa, conviene un respiro antes de meterse a aprender la lengua de aptitude. Estamos deseosos de ver los resultados, pero con lo de hoy basta, que los atracones son causa de muchas indigestiones.


Resumen:

  • HAL es una work in progress fruto de la colaboración de un gran número de entusiastas de todo el mundo.

  • HAL es una máquina programable.

  • Los programas que hacen de HAL lo que es se distribuyen agrupados en paquetes.

  • Los paquetes se reúnen en almacenes disponibles vía Internet.

  • Cuando se instala una distribución, lo que se instala es un conjunto amplio de paquetes básicos.

  • Para que HAL pueda hablar de más cosas, aparte de las básicas, es necesario instalar nuevos paquetes.

  • Cuando los argumentos que añadimos a una orden constan de varias palabras separadas por espacios, ese grupo de palabras debe estar entre comillas.

  • Un hacker es alguien que goza con lo que para el resto de los mortales es dureza, dificultad, fealdad y peligro.

  • Un usuario requiere de interfaces que le oculten y suavicen las cosas duras, difíciles, feas y peligrosas.

  • aptitude es un amistoso ayudante de HAL especializado en la gestión de los paquetes de las distribuciones basadas en Debian.

viernes, 23 de enero de 2009

HAL y las lenguas: conclusiones

Con la miniserie sobre HAL y las lenguas, que nos ha ocupado nada menos que cinco artículos sin contar con éste, hemos realizado una experiencia real de lo que es un tipo de trabajo habitual con HAL.

El objetivo primordial era no sólo hacer que HAL nos hablara en la lengua o lenguas deseadas, sino, sobre todo, experimentar en vivo la forma que adopta un diálogo con HAL dirigido a la realización de una tarea concreta, los procedimientos que habitualmente se ponen en juego y las órdenes que más frecuentemente se utilizan.

Consciente de la dificultad que esta primera inmersión en una situación real de diálogo puede tener para el principiante, me parece oportuno esquematizar la conversación propiamente dicha y extraer algunas conclusiones útiles para el futuro.

Recordemos, antes de empezar, la tarea que nos propusimos llevar a cabo. Se trataba de hacer que HAL nos hablase, a nosotros particularmente, en una lengua diferente al inglés, sin que ello afectase a la lengua que otros usuarios decidiesen establecer. Si esta nueva lengua fue la que elegimos en el momento de la instalación, parte de la tarea habrá sido asumida por el arquitecto de la distribución. Por eso, es mejor plantearse el caso más difícil posible, un caso en el que el arquitecto seguramente no haya tomado parte, por ejemplo, el japonés. Por tanto, la tarea concreta que nos propusimos fue hacer que HAL nos hablase primero en castellano y después en japonés.

Veamos paso por paso cuál fue nuestra conversación. Para facilitar la lectura adopto las siguientes convenciones:

  • Nuestras intervenciones van precedidas de la palabra YO.

  • Las intervenciones de HAL van precedidas de la palabra HAL.

  • Nuestras meditaciones, lo que pensamos antes de hablar con HAL, pero que no le decimos, irán en cursiva.

  • Los comentarios del autor a la conversación van entre corchetes.



Hechas estas aclaraciones, recordemos cómo fue el diálogo:

YO:
Voy a pedirle a HAL que me diga cuál es mi entorno local en este momento.

locale


HAL:

LANG=C
LANGUAGE=C
LC_CTYPE=C
LC_NUMERIC=C
LC_TIME=C
LC_COLLATE=C
LC_MONETARY=C
LC_MESSAGES=C
LC_PAPER=C
LC_NAME=C
LC_ADDRESS=C
LC_TELEPHONE=C
LC_MEASUREMENT=C
LC_IDENTIFICATION=C
LC_ALL=


YO:
Y de estas variables ¿cuáles tendré que cambiar?, ¿todas, sólo algunas? Voy a pedir ayuda a HAL sobre la orden anterior.

locale --help


HAL:

Usage: locale [OPTION...] NAME
or: locale [OPTION...] [-a|-m]
Get locale-specific information.

System information:
-a, --all-locales Write names of available locales
-m, --charmaps Write names of available charmaps

Modify output format:
-c, --category-name Write names of selected categories
-k, --keyword-name Write names of selected keywords
-v, --verbose Print more information

-?, --help Give this help list
--usage Give a short usage message
-V, --version Print program version


YO:
¡Vaya! No entiendo bien esta respuesta, aparte de estar en inglés. Voy a preguntar a HAL que me muestre el manual de operaciones. Seguro que tiene uno.

man


HAL:

What manual page do you want?


YO:
Parece que el manual contiene varias páginas. Le voy a pedir la referente a locale.

man locale


HAL:

[HAL muestra la página de manual de locale. Como es larga, omito la respuesta. En lo sucesivo omitiré las respuestas muy largas de HAL.]


YO:
La respuesta sigue en inglés, intentaré leerla. ¡Ah!, parece que la variable LC_MESSAGES puede ser útil. Voy a probar a poner esta variable al castellano y volver a solicitar una página de manual, esta vez la relativa al manual mismo.

LC_MESSAGES=es_ES.UTF-8 man man


HAL:

[HAL muestra la página de manual de man.]


YO:
Bien, la opción -a de man me puede ser útil. Con ella le voy a pedir a HAL que me muestre todas las páginas de manual relativas a locale, a ver si descubro algo interesante en ellas.

man -a locale


HAL:

[HAL muestra todas las páginas del manual sobre locale.]


YO:
La página de locale de la sección 7 parece interesante. Le pediré a HAL que me la muestre en castellano.

LC_MESSAGES=es_ES.UTF-8 man 7 locale


HAL:

[HAL muestra la página del manual de locale, sección 7.]


YO:
O sea, que las variables que tengo que cambiar son LANG, LANGUAGE y LC_ALL. Bien, sé ---por el autor, que me lo ha soplado--- que debo modificar mi fichero .bashrc y añadirle estas variables con el valor adecuado para el castellano, que es es_ES.UTF-8. Primero voy a comprobar si estas variables existen ya en ese fichero. Le pediré a HAL que me las busque dentro de él.

grep LANG .bashrc


HAL:

[Silencio.]


YO:
El silencio de HAL significa que la variable no existe en .bashrc. Pruebo también con las otras dos, y tampoco existen. Las voy a añadir al final del fichero con la configuración para el castellano.

echo -e "LANG=es_ES.UTF-8\nLANGUAGE=es_ES.UTF-8\nLC_ALL=es_ES.UTF-8" >>.bashrc


[Pasado un cierto tiempo ...]

Lo he pensado mejor y he decidido cambiar la configuración local que acabo de establecer y en lugar de en castellano, la voy a poner en japonés, es decir, el valor de las variables deberá ser ahora ja_JP.UTF-8. Primero le pediré a HAL que me haga una copia de .bashrc con el nombre .bashrc_ORIGINAL, para tenerlo siempre a mano, por si luego cambio de idea.

cp .bashrc .bashrc_ORIGINAL

Ahora ya puedo cambiar sin miedo .bashrc. Le diré a HAL que llame a su asistente sed y le pida que sustituya 'es_ES' por 'ja_JP' en el fichero .bashrc_ORIGINAL y que guarde los cambios en .bashrc. De esta forma .bashrc quedará modificado con la adaptación japonesa y .bashrc_ORIGINAL contendrá la copia antigua, la adaptada al castellano.

sed 's/es_ES/ja_JP/' .bashrc_ORIGINAL >.bashrc

Todavía no sé, sin embargo, si esta configuración a nivel de usuario va a funcionar. Tengo que comprobar antes si el soporte para el japonés está entre las "localizaciones" disponibles. Por tanto, le voy a pedir a HAL que me diga cuáles lo están en este momento. Sé cómo hacerlo después de releer la página de manual de locale:

locale -a


HAL:

C
es_ES.utf8
POSIX


YO:
Mala suerte, el soporte para el japonés no está disponible. Me las tengo que arreglar para saber qué tengo que hacer ahora. Quizá HAL sepa de algunas órdenes en relación con la "localización" del sistema. Se lo preguntaré.

apropos locale


HAL:
[Un fragmento de la respuesta de HAL]

...
locale-gen (8) - generates localisation files from templates
locale.gen (5) - Configuration file for locale-gen
...


YO:
Estas órdenes parecen pertinentes. Voy a ver qué dice la página de manual de la sección 8 sobre locale-gen.

man 8 locale.gen


HAL:

[HAL muestra la página de manual de locale.gen, sección 8.]


YO:
¡Estupendo! Queda muy claro lo que hay que hacer: modificar el fichero /etc/locale.gen y ejecutar locale-gen. Antes, voy a comprobar si hay algo sobre el japonés (con codificación UTF-8) en ese fichero:

grep ja_JP.UTF-8 /etc/locale.gen


HAL:

# ja_JP.UTF-8 UTF-8


YO:
Efectivamente, hay algo, pero está comentado. Tengo que modificar, pues, el fichero para descomentar esta línea. Pero, antes de realizar la modificación, hago como siempre una copia del fichero que voy a modificar:

cp /etc/locale.gen /etc/locale.gen_ORIGINAL


HAL:

cp: no se puede crear el fichero regular «/etc/locale.gen.ORIG»: Permiso denegado


YO:
Ya veo. Como es un fichero de configuración global, debo adoptar el papel de root para realizar modificaciones en el directorio /etc o en cualquiera de sus ficheros. Le diré a HAL que quiero cambiar de usuario y convertirme en superusuario:

su

Bien. Escribo la contraseña y me convierto en superusuario.


YO (root):
Ahora, como root volveré a pedir a HAL que me haga copia del fichero /etc/locale.gen.

cp /etc/locale.gen /etc/locale.gen_ORIGINAL

¡Funciona! Ahora tengo que descomentar la línea relativa al locale que me interesa. Ya sabes, HAL, llama a tu ayudante sed y pídele que quite el carácter de comentario que ha quedado en el fichero /etc/locale.gen_ORIGINAL y que guarde el cambio en el fichero locale.gen:

sed 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen_ORIGINAL >/etc/locale.gen


Solo falta reconstruir los locales. Puesto que ahora el soporte para el japonés está activado en el sistema, le pediré a HAL que vuelva a generar todos los locales, esto hará funcionar mi configuración personal en .bashrc:

locale-gen

Y ahora a respirar. Dejaré de ser root.

exit


YO:
Abriré un nuevo emulador de terminal, y desde él le pediré a HAL que me diga la fecha, a ver si efectivamente aparece en japonés:

date


HAL:

2009年 1月 22日 木曜日 16:50:56 CET


YO:
Arigato, HAL. Tarea terminada.


Esta fue la conversación. Interesante e instructiva. Más larga de lo que realmente es cuando se está familiarizado con la lengua de HAL. Adquirido el hábito, pensar y hablar tendrán lugar simultáneamente y a toda velocidad.

No muy diferentes en esencia van a ser otras conversaciones encaminadas a la realización de tareas. El patrón es siempre el mismo. Una vez que hemos definido claramente lo que queremos hacer, aplicamos las órdenes que conocemos. Si queremos saber más sobre ellas o sobre órdenes semejantes, recurrimos a la propia ayuda interna de HAL, que es, salvo raras excepciones, la más completa que existe. Esta ayuda es, como hemos visto, de tres clases:

  • Consulta rápida de las opciones de una orden: mediante la opción --help.

  • Consulta detallada sobre una orden: mediante la orden man.

  • Consulta sobre órdenes relativas a algún asunto: mediante la orden apropos.


Aparte de las órdenes que devuelven mensajes puramente informativos o de aquellas que manipulan globalmente ficheros como cp o mv, un gran número de tareas requiere de la edición de ficheros de texto. Para eso son muy útiles órdenes como grep, que busca fragmentos dentro de un fichero, y sed, que permite transformar rápidamente ficheros. Hay más órdenes fundamentales en el tratamiento de ficheros, que probablemente veamos en el futuro. Tan fundamentales o más son las construcciones sintácticas que hacen posible la redirección. Hemos visto sólo una. Pronto habrá que ver la versión extrema y más versátil de ella: las tuberías. Eso queda para otra ocasión.

jueves, 22 de enero de 2009

Ohayo, HAL

Vamos a repasar por donde estamos en la senda que hemos iniciado junto a HAL para tratar de hacerle responder en la lengua que nos plazca, porque entre tantas idas y venidas y recovecos varios quizá andemos perdidos o casi mareados. Prometo que, al final, daré un esquema o mapa de todo el recorrido. Y estamos cerca, muy cerca, de ese final.

De momento valdrá echar la vista atrás para ver el paisaje que queda al fondo.

Nuestro objetivo inicial fue pedirle a HAL que nos respondiera en castellano, a lo Sancho Panza, pero en fino, es decir, en la forma en que HAL entiende la finura, que es para muchos fría como el hielo y para unos pocos, entre los cuales se encontrará el lector al cabo de estas charlas, cálida como el retorno al hogar.

Logramos que lo hiciera temporalmente, para cada pregunta que le hacíamos. Pero no contentos con esto nos propusimos que nos descargase del trabajo de solicitarle continuamente la respuesta en castellano. También conseguimos esto, modificando su propia configuración, la que tiene establecida para nosotros en particular. El resto ---los demás usuarios--- que se apañen como puedan.

Pero no hemos querido quedarnos ahí y hemos decidido poner a prueba a HAL para que ahora nos hable en la lengua nipona, una que, a buen seguro, el esforzado arquitecto de nuestra distribución ni siquiera pensó que nos interesase. Ayer mismo, y por un nuevo atajo, reprodujimos los pasos dados en nuestra previa castellanización para niponizar a HAL.

Pero ahí no podemos quedarnos, porque HAL seguramente no ha sido preparado por el citado arquitecto para que nos hable precisamente en japonés. (Habrase visto qué retorcidos somos, pensará el susodicho). La configuración a nivel de usuario es correcta, pero falta algo más para que tenga efecto.

Así es que lo que nos resta por hacer es preparar nosotros mismos a HAL para que acepte los cambios que efectuamos en nuestra configuración personal. Adoptaremos, en cierto modo, el papel del arquitecto. Algo que no debería hacerse a estas alturas de nuestros conocimientos. Pero ya nos hemos metido en el berenjenal y no queremos dar marcha atrás. Eso sí, habrá que tener ahora sumo cuidado y prometer que trataremos de no asumir papeles de tal responsabilidad, salvo cuando sea estrictamente necesario. Prometámoslo en serio, y sigamos con la atención bien concentrada y los nervios a flor de piel, porque la responsabilidad entraña un peligro y el peligro pone los pelos de punta.

Si volvemos a requerir ayuda a HAL sobre la orden locale ---recuerde el lector que esto se hace gritándole a HAL lo siguiente: locale --help---, veremos que hay una opción interesante de esa orden, la opción -a, que nos informa de las "localizaciones" que HAL tiene disponibles en este momento. Dicho de otro modo, nos informa de para qué configuraciones locales está HAL predispuesto. Aquellas para las que no esté predispuesto no funcionarán, por mucho que nos empeñemos en modificar nuestros ficheros privados de configuración de usuario, en concreto, nuestro fichero .bashrc.

Hagamos, pues, la consulta:


locale -a


El lector verá algo parecido a esto:


C
es_ES.utf8
POSIX


Los locales C y POSIX son básicamente sinónimos y aluden a la configuración local por defecto, la que habrá si no se especifica otra. O sea, un inglés, puro y duro, y sin matices. Por suerte hay soporte para otro entorno local, aparte del puro y duro. Es el soporte para el español de España. Las gracias hay que dárselas al arquitecto de nuestra distribución.

La pregunta del millón para nosotros es, naturalmente, si es posible hacer que HAL disponga también del soporte para el japonés, si hay manera de generar un ja_JP.UTF-8 que de cuya disponibilidad nos informe también locale -a. Tiene que haberla, y la vamos a descubrir ahora, cueste lo que cueste.

¿Por dónde empezar? Quizá haya alguna otra orden semejante a locale relacionada con lo que deseamos.

¿Por qué no preguntárselo a HAL? Sabemos ya que nos puede dar información sobre el significado y utilidad de una orden concreta, con la pregunta whatis, que vimos al final del otro día. Por ejemplo, podemos preguntarle:

whatis locale

¿No será también capaz de decirnos algo cuando no sabemos el nombre exacto de la orden, sino que simplemente barruntamos más o menos de qué puede tratarse? Algo parecido a cuando preguntamos a un amigo no informático: "Oye, tú que sabes a propósito de HAL. ¿Te suena?".

Probemos, probemos:

Oye, HAL, tú que sabes a propósito de locale

que se expresa de forma muy parecida en la lengua de HAL:

apropos locale

La respuesta, un tanto oscura, nos da descripciones del significado y utilidad de un número considerable de órdenes que tienen que ver con el entorno local. Quizá, por lo dicho antes, nos llamen especialmente la atención estas dos:


locale-gen (8) - generates localisation files from templates
locale.gen (5) - Configuration file for locale-gen


Si leemos la página de manual locale-gen(8), una página de manual de la sección 8, que es la que corresponde al manual para administradores, descubrimos que hemos dado en el clavo. En resumen, lo que ahí se cuenta es que para que el soporte de una localización específica esté disponible se debe, en primer lugar, modificar el fichero /etc/locale.gen, quitando el signo # en la línea donde consta el nombre del soporte local que nos interesa activar, y, en segundo lugar, ejecutar la orden locale.gen

Vamos, para empezar, a ver si hay una línea en /etc/locale.gen que haga referencia al soporte japonés, o sea una línea que contenga ja_JP.UTF-8. Sabemos que para conseguirlo hemos de utilizar la orden grep:

grep ja_JP.UTF-8 /etc/locale.gen

HAL devuelve lo siguiente:

# ja_JP.UTF-8 UTF-8

O sea, que el soporte existe, pero no está activado, porque, para que lo estuviera, debería aparecer sin el signo # delante. Digamos de paso que este signo es muy frecuente en los ficheros de configuración y su función es lo que técnicamente se llama comentar la línea que viene después de él. Una línea comentada es una línea que HAL pasa por alto, que no existe para él, que sólo existe para los humanos que leen el fichero. Se utiliza mucho para hacer comentarios sobre las instrucciones que se le dan a HAL y que a veces son tan oscuras para potenciales lectores humanos que requieren de una explicación previa. También se usa, como en el presente caso, para desactivar instrucciones que luego podrán reactivarse fácilmente, descomentándolas.

Deberíamos, por tanto, descomentar la dichosa línea. Pero, lo primero es lo primero, no tocar un fichero de configuración sin antes realizar una copia de él:

cp /etc/locale.gen /etc/locale.gen_ORIGINAL

Pero HAL, contra todo pronóstico, nos responde lo siguiente:

cp: no se puede crear el fichero regular «/etc/locale.gen.ORIG»: Permiso denegado


¡Pero qué es esto! ¿Cómo se atreve HAL a negarse a cumplir nuestras órdenes? Resulta que ahora nos niega el derecho de hacer lo que pedimos. ¿Acaso no somos nosotros los que mandamos?

No lo somos. Nosotros somos simples usuarios, usuarios de andar por casa, por nuestro home, se entiende. Ahí sí mandamos. Pero en HAL hay zonas reservadas a usuarios competentes y sabios, hay espacios donde a los usuarios del montón ---o sea, a nosotros--- no se nos permite realizar modificaciones ---y copiar un fichero en ellos es realizar modificaciones. El directorio /etc es uno de esos espacios, porque, a pesar de su insignificante nombre, reúne, nada menos, que todos los ficheros de configuración globales del sistema, es decir, todos los ficheros que hacen que HAL sea el que es para todos sus usuarios, nosotros y cualesquiera otros. Es natural que HAL no permita a cualquiera modificar aspectos que pueden afectar seriamente a la totalidad del sistema.

Pero si a nosotros nos lo prohíbe, debe de haber alguien al que se lo permita, un superjefe, el omnisciente y omnipotente usuario que pueda atravesar todas las puertas y posea todos los privilegios. ¿Existe alguien así? ¿Quién es?

Existe, es el superusuario, también llamado root. Lo absurdo, sin embargo, es que nosotros mismos procedimos a la instalación y no conocemos de la existencia de ningún otro usuario por aquí dentro. ¿Dónde está ese superusuario, si yo mismo soy el único que, aparte del arquitecto, se las ha visto con HAL cara a cara?

Ese superusuario no es más que otro papel, que nosotros mismos, únicos usuarios a día de hoy del sistema, podemos adoptar. Hemos salido a escena con nuestro traje y nuestras armas de usuario del montón. Pero podemos, si en verdad somos los únicos usuarios del sistema, cambiar de vestuario y pertrecharnos de armas superpotentes. HAL está diseñado para que asumamos este papel con plena conciencia de la responsabilidad que implica y de los atropellos que podemos cometer si obramos al tuntún. Por eso nos da de entrada el papel de usuario común y nos permite cambiarnos de máscara únicamente previa solicitud expresa nuestra. De esta forma, nos protege de nosotros mismos, de nuestras veleidades. Nos fuerza a tomarnos en serio la representación de superusuario cada vez que queramos convertirnos en él.

¡Vale! Pero como adoptamos el nuevo papel de root. ¿Cómo le indicamos a HAL que nos conceda provisionalmente este privilegio. La orden para ello es su (abreviatura de switch user, que en castellano significa "cambiar de usuario"). En otros sistemas, por ejemplo, los basados en Ubuntu, la orden es sudo (abreviatura de superuser do, que significa "actuar como superusuario"). [Téngase en cuenta que su permite cambiarse por cualquier usuario del sistema y, que si no se indica ningún nombre de usuario como argumento, cambia directamente al usuario root.]

Asumamos, pues, el papel de superusuario:

su

Nos pedirá una contraseña que tuvimos que crear al comienzo de la instalación o que vendrá documentada en el manual de la distribución.

[Si estuviésemos en una distribución que requiere sudo, en lugar de su, después de sudo y separada por un espacio se escribe la orden que queremos ejecutar como root. La contraseña será la misma que la de nuestro usuario normal.]

El "mensaje de bienvenida" ha cambiado para indicarnos que ahora somos root. Logrado el nuevo privilegio podemos intentar la solicitud de copia que quedó pendiente:

cp /etc/locale.gen /etc/locale.gen_ORIGINAL

Ahora sí ha funcionado, el silencio de HAL lo delata.

Procedamos, entonces, a modificar el fichero /etc/locale.gen, de nuevo como root, porque estamos cambiando un fichero de configuración del sistema. Tenemos, lo hemos dicho antes, que descomentar la línea relativa al soporte para japones. Sabemos desde el día pasado que se puede conseguir pidiéndole a HAL que recurra a su ayudante sed

sed 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen_ORIGINAL >/etc/locale.gen


sed permite hacer lo mismo con menos esfuerzo mediante expresiones regulares, pero todavía no sabemos de qué van tales engendros. Para el caso es lo mismo.

Estoy seguro de que el lector ya no aguanta sin ver el resultado. "Estamos actuando a ciegas desde hace días", dirá, "sin ver las consecuencias de nuestros cambios". Mal dicho, pues siempre podría haber recurrido a grep. Pero para acallar las protestas intestinas que puedan haber brotado, propongo que el lector haga:

more /etc/locale.gen

y que vea con sus propios ojos el fichero completo, pulsando la tecla de espaciado cuando quiera pasar de página, porque el fichero consta de varias.

Sólo queda una operación, como ya leímos en la página de manual locale-gen(8) comentada anteriormente. La operación la debe realizar el superusuario, que sigamos siendo nosotros, de momento. Ya sabes, HAL:

locale-gen

Colorín colorado. Y ahora a ver el resultado.

Lo primero, fundamental, es desembarazarnos del peso del disfraz de root, saliendo inmediatamente del escenario de los superpoderes, si es que entramos con su para ser root:

exit

¡Qué alivio! Volvemos a ser nosotros, usuarios sin compromisos ni responsabilidades insoportables. Estamos donde siempre y somos los de siempre ---se puede comprobar con whoami y pwd.

Ahora el lector, si siguió el consejo que propuse al final de la entrada anterior, tiene todavía su .bashrc adaptado al entorno castellano. Debe cambiarlo provisionalmente para amoldarlo al entorno nipón, tal como se explicó paso por paso en dicha entrada.

Una vez realizada esta readaptación orientalizante, abramos una nueva ventana de emulador de terminal y pidámosle a HAL algo, por ejemplo, que nos diga la fecha y hora actuales ---todavía no se lo hemos pedido nunca:

date

Y aquí la tiene, tal como la escribiría un samurai de los tiempos presentes:

2009年 1月 22日 木曜日 16:50:56 CET

El lector puede seguir jugando por su cuenta con el japonés. Al terminar debería volver a cambiar su .bashrc al estado castizo anterior, a no ser que se desenvuelva bien en Nihongo y no encuentre problemas con kanjis y hiraganas o katakanas.

Sajonara, HAL.

Y el resumen:

  • Si queremos preguntar a HAL sobre una orden cuyo nombre desconocemos o no recordamos con claridad conviene consultarle con apropos.

  • El directorio /etc contiene ficheros de configuración global de HAL.

  • El signo # al inicio de una línea es común en los ficheros de configuración y sirve para realizar comentarios a las instrucciones que lee HAL o para ocultar de su vista fragmentos de ese fichero.

  • El superusuario o root es el usuario de HAL con todos los privilegios y poderes.

  • Las tareas administrativas que afectan al sistema en su conjunto, suelen tener que realizarse como root.

  • Para ser root se usan las órdenes su o sudo, dependiendo de la configuración de que dispongamos.

  • De una sesión iniciada con su se sale con exit.

  • more nos muestra el contenido de un fichero, página a página.

  • date nos muestra la fecha y hora actual.