2. bash y el juego de herramientas

Indicadores de Logros

2.1. Lectura: bash y el juego de herramientas

El intérprete de comandos puede ser un gran aliado de usuarios, administradores y programadores, porque permite automatizar labores rutinarias y componer diversos programas para que interactúen y realicen labores complejas.

La idea para componer diversos programas es formar "tuberías" en las que cada tubo es un programa cuya salida se conecta como entrada a otro. Esta idea se comenzará a desarrollar en esta guía, introduciendo primero algunas facilidades del intérprete de comandos bash [31] para editar comandos, después se presentarán algunos programas y comandos de bash y finalmente se presentará como se compone y se controla el flujo de datos.

2.1.1. Ayudas interactivas de bash (readline y history)

Para recibir información del usuario bash y otros programas emplean las librerías readline y history. readline brinda facilidades para escribir comandos con un teclado y history almacena los últimos comandos que el usuario haya dado para facilitar su reutilización. Algunas de las posibilidades que estas librerías ofrecen son:

Flechas o Control-p, Control-n

Para "navegar"sobre la historia de comandos

Completación con Tab

Puede emplear la tecla Tab para completar nombres de programas, de máquinas (mencionadas en el archivo /etc/hosts) o de usuarios, si hay varias posibles completaciones un segundo Tab presentará la lista de posibilidades. Por ejemplo: si estando en bash teclea chm y después presiona Tab, se completará el nombre del comando a chmod; si teclea ls /usr/inc y presiona Tab se completará la vía /usr/include; si teclea finger @ y después Tab dos veces verá los nombres de algunas máquinas conocidas por su sistema; si teclea ls ~ y presiona Tab dos veces verá los nombres de usuarios (ls ~carlos mostrará el contenido del directorio personal del usuario con login carlos).

Edición con teclas de emacs o vi

readline puede configurarse para efectuar algunas operaciones de edición bien con las teclas de emacs o bien con las de vi. Por ejemplo cuando las teclas de emacs están configuradas (que es la opción por defecto) puede emplear las flechas hacía atrás y adelante (o Control-f y Control-b) para devolverse o avanzar sobre el comando; Control-a para ir al comienzo; Control-e para ir al final; Control-k para cortar el resto del comando; Control-y para insertar el texto antes cortado. Cuando las teclas de vi están configuradas puede presionar ESC para pasar a modo comando y usar las teclas h, j, k y l (o las flechas) para moverse o f para buscar una letra en la línea que está editando.

Buscar comandos en la historia de comandos

Puede buscar un comando entre los que ya ha tecleado para reutilizarlo. Con el modo emacs emplee Control-r y comience a teclear el comando que busca --es una búsqueda incremental, en el modo vi emplee / y después teclee parte del comando que busca.

2.1.2. Algunas herramientas

Un sistema Linux cuenta con gran cantidad de herramientas, cada una de las cuales realiza una labor muy específica pero rápidamente y bien; en esta sección presentamos unas cuantas típicamente usadas para procesar textos planos. Junto con cada herramienta presentamos algunas de sus opciones y ejemplos de su uso (la documentación completa de cada herramienta puede consultarse en la página del manual o en la documentación info).

cat, tac, nl, more, less, head, tail

Permiten ver uno o más archivo o parte de un archivo. cat y tac presentan los archivos que reciben uno a continuación de otro, aunque tac los presenta invertidos. La orden:

cat /etc/profile /etc/hostname

presenta el archivo /etc/profile y a continuación /etc/bashrc. cat entre sus opciones acepta -n con la cual numera las líneas, aunque esa labor puede hacerse mejor con nl. more y less permiten al usuario "desplazarse" sobre uno o más archivos empleando teclas (e.g barra espaciadora para avanzar una página), less permite también buscar y acepta algunos comandos como los de vi. head y tail muestran parte del comienzo o del final de un archivo, por defecto 10 líneas aunque puede especificarse la cantidad de líneas con la opción -n o puede especificarse la cantidad de bytes con la opción -c.

split, csplit

Dividen un archivo en varias partes. split divide empleando como criterio un tamaño, mientras que csplit divide de acuerdo al contexto ---divide cada vez que en el texto aparezca una cadena [32] o patrón. split acepta como opciones para especificar el tamaño -b y -l, el primero seguido del tamaño en bytes y el segundo seguido del tamaño en líneas. Por ejemplo, para dividir un archivo grande en partes de 100000 bytes:

split -b 100000 grande

las partes quedarán en archivos con nombres como xaa, xab, etc. Para dividir un archivo dir.txt siempre que la palabra nombre aparezca:

csplit dir.txt /nombre/ {*}

En el ejemplo anterior la cadena por buscar [33] se especificó a continuación del nombre del archivo entre los caracteres '/', la cadena final "{*}" indica que debe dividirse cada vez que se encuentre una nueva ocurrencia de nombre, si no se usa csplit sólo buscará la primera ocurrencia y dividirá el archivo en dos partes, si en vez de * se emplea un número csplit buscará a lo sumo esa cantidad de veces la palabra y dividirá el archivo por cada ocurrencia que encuentre.

sort

Por defecto ordena las líneas de un archivo, con la opción -m mezcla dos archivos ordenados y con la opción -c verifica que un archivo esté ordenado. Al ordenar puede considerar las líneas completas, considerarlas números enteros (opción -n) o flotantes (opción -g), considerarlas meses (opción -M) o dividirlas en campos y emplear algunos campos como llaves de ordenamiento (opción -k para especificar llaves y -t para cambiar separador de campos). En las comparaciones puede ignorar diferencias entre mayúsculas y minúsculas con la opción -f, puede ordenar de mayor a menor con la opción -r ---por defecto ordena de menor a mayor--- y puede eliminar líneas repetidas con la opción -u [34].Por ejemplo para ordenar por líneas el archivo nombres.txt:

sort nombres.txt

si cada línea del archivo nombres.txt tiene el apellido y después el nombre de una persona separados por espacios, puede ordenarse por nombre con:

sort -k 2 nombres.txt
wc

Cuenta cantidad de palabras, líneas y caracteres en uno o más archivos. Por defecto presenta los tres datos por cada archivo que reciba y después presenta las sumas. Con la opción -c presenta la cuenta de palabras, con -l la cuenta de líneas, con -w la cuenta de palabras y con -L la longitud de la línea más larga.

2.1.3. Redirección y tuberías

En Unix, todo programa tiene 3 canales estándar para intercambiar información con el usuario, con el hardware o con otros programas: salida estándar, entrada estándar y error estándar, que verá abreviados como stdout, stdin y stderr respectivamente. Estos canales pueden conectarse a archivos, a dispositivos o a canales de otros programas (tuberías). Por defecto la entrada estándar es el teclado, mientras que la salida y el error estándar son la pantalla.

Por ejemplo los programas cat y sort si no reciben un archivo como parámetro esperan información de la entrada estándar y envián el resultado de su operación a la salida estándar; para comprobarlo ejecute el programa cat o el programa sort sin argumentos.

Para redireccionar la salida estándar a un archivo se agrega al final del comando una cadena de la forma "> nombre_archivo". Por ejemplo para ordenar un archivo palabras.txt y dejar el resultado en ord.txt:

sort palabras.txt > ord.txt

Para redireccionar el error estándar a un archivo se agrega tras el nombre del comando 2> nombre_archivo [35]. Por ejemplo:

cat /ceq11 2> err.txt

escribirá en el archivo err.txt un mensaje como "cat: /ceq11: No existe el fichero o el directorio" ---claro está mientras efectivamente no exista el archivo /ceq11. Pueden redireccionarse tanto salida estándar como error estándar simultáneamente, por ejemplo:

cat /etc/fstab > /dev/null 2> /dev/null

redireccionará tanto salida como error estándar al dispositivo /dev/null ---El dispositivo /dev/null es como un agujero negro, todo lo que envié ahí desaparece (ver Ubicación de archivos y directorios).

Por defecto al redireccionar con > a un archivo, se crea un nuevo archivo, en caso de que ya existiera su contenido previo se pierde y es remplazado por la información redireccionada. Por ejemplo después de ejecutar la secuencia:

sort 1.txt > ord.txt
sort 2.txt > ord.txt

quedará en ord.txt únicamente el contenido de 2.txt ordenado. Para agregar la información redireccionada al final de un archivo ya existente puede emplear >> en lugar de >, retomando el ejemplo anterior:

sort 1.txt > ord.txt
sort 2.txt >> ord.txt

dejará en ord.txt el contenido de 1.txt ordenado y a continuación el de 2.txt ordenado.

Para lograr que la entrada estándar sea leída de un archivo, se agrega al final del comando < nombre_archivo. Por ejemplo

head  < arc.txt

presentará las 10 primeras líneas del archivo arc.txt (es equivalente a head arc.txt o a head - < arc.txt [36]). Poder redireccionar la entrada estándar de un programa puede ahorrarle tiempo, porque puede escribir la secuencia de líneas que desea enviar al programa en un archivo y después repetirla tantas veces como desee. Por ejemplo para enviar el mismo correo electrónico a varias personas puede escribirlo en un archivo correo.txt y después ejecutar algo como:

mail usuario1@micolegio.edu.co usuario2@micolegio.edu.co < correo.txt.

Empleando redireccionamiento y los comandos y programas que ya se han presentado se pueden hacer rápidamente muchas labores. Un ejemplo es dividir un archivo grande para transportarlo en varios disquetes: con split -b 1000000 grande.gz divide el archivo grande.gz en varias partes, cada una de las cuales cabe en un disquete (digamos que queda dividido en tres partes xaa, xab y xac). Puede copiar cada una de las partes en un disquete, llevar los disquetes a otro computador y emplear cat y redireccionamiento para unirlos:

cat xaa xab xac > grande.gz

Otra facilidad para redireccionar entrada estándar es <<, que después de un comando permite escribir un texto que se constituirá en la entrada estándar. A continuación de << debe ponerse una palabra, escogida por usted, que indicará fin de entrada. La entrada estándar constará de las líneas que se digiten a continuación hasta la primera que contenga sólo la palabra que indicaba fin de entrada. Por ejemplo:

sort <<FIN
pábulo
opíparo
FIN

ordenará las palabras dadas (excepto FIN que indica el fin de la entrada). Así, << es equivalente a editar un archivo y después redireccionarlo a la entrada estándar de un programa.

El operador de composición '|' permite redireccionar la salida de un comando en la entrada estándar de otro (es como pegar dos tubos). Por ejemplo:

ls -l / | wc -l

mostrará la cantidad de archivos y directorios en el directorio /. Al ejecutar ls -l / se envía a salida estándar la lista de archivos del directorio raíz, cada uno en una línea, con '|' esta salida se convierte en entrada de wc -l; el programa wc con la opción -l presenta sólo la cantidad de líneas de la entrada estándar.

El ejemplo anterior pudo haberse realizado en dos pasos empleando un archivo temporal, digamos temp.txt:

ls -l / > temp.txt
wc -l < temp.txt

pero claro está, | es más práctico y aún más cuando deben componerse más de dos programas.

2.2. Lecturas recomendadas: bash y el juego de herramientas

  • En esta sección se han presentado unas cuantas de las facilidades de readline y history. Puede consultar más sobre el uso de estas librerías en la página del manual de bash en la sección "READLINE y HISTORY". Hay más información de readline (por ejemplo sobre la configuración) en el manual info de rluserman (Ver (info rluserman)q ).

  • Puede consultar más información sobre las herramientas para procesar textos introducidas en esta sección y sobre otras que no se mencionaron en la documentación info de textutils (Ver (info textutils)).

  • Puede consultar otras explicaciones sobre tuberías y el uso del kit de herramientas Unix en "Linux: Instalación y Primeros Pasos. Sección 3.8 Fontanería UNIX". http://lucas.hispalinux.es/Manuales-LuCAS/LIPP/lipp-1.1-html-1.2/lipp3.htm#3.8 y en la sección "Opening the software toolbox" de la documentación info de textutils (Ver (info textutils )).

2.3. Ejercicios: bash y el juego de herramientas

2.3.1.

Ingrese a una sesión con bash y practique las facilidades interactivas presentadas en esta guía. En particular practique Control-k y Control-y para cortar y pegar líneas, después de usar Control-y emplee Alt-y varias veces (si tiene inconvenientes con Alt-y intentente ESC-y). ¿Para qué se usa Alt-y ?

2.3.2.

¿Qué hace el comando cat datos2.txt > datos3.txt ?

2.3.3.

¿Qué hace el comando ls -Rl ~ | wc -l ?

2.3.4.

¿Qué hace el comando nl /usr/doc/debian/debian-manifesto | less ?

2.3.5.

Dado un archivo resumen.txt, ¿cómo puede determinar si el texto tiene menos de 5000 palabras?

2.3.6.

Dado un archivo correo.txt, ¿cómo puede verificar que todas las líneas tengan menos de 75 caracteres?

2.3.7.

Sin emplear split ni editores de texto, ¿cómo puede dividir un texto pord.txt de 100 líneas, en dos archivos uno.txt y dos.txt el primero con las primeras 40 líneas y el segundo con las últimas 60?

2.3.8.

Dado un archivo con nombres de personas pers.txt ---un nombre en cada línea---, escriba un comando para bash que ordene los nombres y presente sólo los 10 primeros.

2.3.9.

Dada una lista de palabras en un archivo palabras.txt ---una en cada línea---, escriba un comando para bash que presente la cantidad de palabras no repetidas.

2.3.10.

Escriba un comando para bash que muestre la cantidad de archivos de configuración en su directorio personal (ver Lectura Archivos y permisos para repasar que son archivos de configuración).

2.3.11.

Escriba un comando para bash que le envíe a usted un correo electrónico con el listado de los archivos de su directorio personal ordenado alfabéticamente.



[30] tubería: del inglés pipe.

[31] Aunque hay varios intérpretes de comandos para Unix y Linux (ksh, ash, zsh, tcsh y csh), algunos muy buenos, bash es el intérprete de comandos escogido por el proyecto de estandarización de Linux: LSB - Linux Standard Base. http://www.lsb.org

[32] En estas guías y otros documentos relacionados con informática (búsquedas, procesamiento de texto, programación) una cadena es una secuencia de caracteres ---un texto.

[33] Más que una cadena se trata de una expresión regular.

[34] También puede emplear el programa uniq para eliminar líneas repetidas en un archivo ordenado.

[35] Otra forma de redireccionar salida estándar es agregando 1> nombre_archivo. En general n> nombre_archivo permite redireccionar el descriptor de archivo n. Por convención 1 es el descriptor de archivo de salida estándar, 2 el de error estándar y 0 el de entrada estándar. Puede emplear otros números para referenciar nuevos descriptores de archivos.

[36] Varios programas emplean como convención tratar al nombre de archivo - como entrada estándar