Sustitución de parámetros

Los sistemas Linux y otros Unix traen las típicas herramientas como cut, awk y sed para reemplazar o recortar partes de una variable, pero los verdaderos "gurus" utilizan la sustitución de parámetros. Vamos a explicar esto en varios pasos:

1-) Las variables pueden ser referenciadas con $var o con ${var}

VAR='lorem ipsum';
echo $VAR;
echo ${VAR};
2-) La longitud de una variable la obtenemos con ${#VAR}
echo ${#VAR} -> 1
3-) Obtenemos un substring de la variable con ${VAR:POS}
echo ${VAR:6} -> ipsum
4-) También podemos obtener un substring del tamaño que deseamos con ${VAR:POS:LON}
echo ${VAR:0:6} -> lorem
5-) Si deseamos dividir según un patrón de izquierda a derecha utilizamos ${var#pat} o ${var##pat}
VAR2='lorem,ipsum.,datum.sanctum'
echo ${var2#*,} -> ipsum.,datum.sanctum
echo ${var2##*,} -> datum.sanctum
6-) De derecha a izquierda es ${var%pat} o ${var%%pat}
echo ${var2%,*} -> lorem,ipsum.
echo ${var2%%,*} -> lorem
7-) La sustitución es igual de sencilla ${var/pat/ree} o ${var//pat/ree}
echo ${var2/m/M} -> loreM,ipsum.,datum.sanctum
echo ${var2//m/M} -> loreM,ipsuM.,datuM.sanctuM
OK? Un uso muy interesante de todo esto? Por ejemplo, para renombrar muchos ficheros de IMAGEN a imagen:
for i in *
do
mv ${i} ${i/IMAGEN/imagen}
done
Magia!

Script!

Script es una aplicación muy, pero que muy útil para todos aquellos quienes como yo somos un tanto olvidadizos. Además, configurando correctamente nuestro PS1 podemos generar reportes de uso.
Script sencillamente almacena todo que aparece en pantalla después de que se ejecuta. Por ejemplo:

$script -a /tmp/log.txt

De ahora en adelante, toda la sesión será almacenada en el fichero indicado. Para terminar pulsamos Ctrl+D

Pero la opción realmente chula de script es -f. Supongamos que tenemos a un usuario nuevo y queremos "monitorizar" lo que hace. Hacemos que éste ejecute:

$script -f -a /tmp/luser.log

Luego para ver lo que está haciendo en tiempo real utilizamos tail:

#tail -f /tmp/luser.log

Muchos juegos se le pueden dar a esta aplicación tan útil. Por cierto, no intenten ejecutarla desde el .bashrc que por alguna razón crea varios procesos repitiendo la salida de los comandos

Entradas y salidas estandar de Bash

La base de la programación de scripts en Bash son los descriptores de ficheros, es decir, stdin y stdout. Estos son básicamente los dos medios que utilizamos para comunicarnos con una aplicación en Bash: stdin escucha y stdout habla, así de sencillo.
Por lo tanto, cuando un programa está siendo ejecutado y utiliza una función del tipo echo, print o println, lo que sea que vaya a escribir, lo hará a stdout.
El uso más común y quizás el más útil de estos descriptores, es el llamado "piping": enviar la salida (stdout) de un programa como entrada (stdin) para otro.
El ejemplo más sencillo es utilizar "ls" para mostrar el contenido de un directorio, el cual, dada la gran cantidad de ficheros, nos es imposible de contener dentro de una pantalla de consola. Utilizando otra utilidad como "less" o "more" podemos realizar una pausa entre cada salto de pantalla para verificar los ficheros. Algo así como el dir /p de DOS:

$ ls -l

Devuelve una lista demasiado larga para que podamos verla. Por esto vamos a utilizar el "piping" para dirigir la salida (stdout) de ls -l hacia la entrada (stdin) de more:

$ ls -l | more

Nada complicado hasta ahora. El símbolo "|" (AltGr+1) es el que hace toda la magia. Existen otros dos símbolos mágicos: > y <. Vamos a dar un ejemplo de cada uno y su uso más común. El más sencillo de comprender es > el cual envía la stdout a alguna parte, en este caso, a un fichero.

$ls -la > foo.txt

Si el fichero no existe, es creado y rellenado con la salida (stdout) de "ls -la". Si el fichero existe (muy importante!) todos los datos son reemplazados, así que cuidadin. Además de > podemos utilizar >> lo cual escribe la salida al final del fichero. Por ejemplo, supongamos que foo.txt no existe:

$dmesg >> foo.txt
$cat /var/log/syslog >> foo.txt

Entonces, foo.txt contiene la información de dmesg y el último syslog.

El más complicado puede que sea <. Básicamente lo utilizamos para inyectar algo en el programa que vamos a ejecutar. Supongamos que tenemos una serie de comandos para MySQL en un fichero foo.mysql y queremos ejecutarlos desde la línea de comandos:

$mysql -u root -p < foo.mysql

Hará el truco.
Finalmente, los "File Descriptors" son sólo un nombre chulo que darles a stdin (File descriptor 0) y stdout (File descriptor 1).

Correos de actualizaciones

Si se tienen varios servidores funcionando, es un poco complicado mantenerse al día de las actualizaciones disponibles a través de aptitude. Leyendo entre los paquetes disponibles para instalar encontré dos que me llamaron la atención: apticron y cron-apt.
Decidí instalar cron-apt en un equipo y probarlo. Es muy sencillo de utilizar y me vino como anillo al dedo. Ahora recibo correos con las actualizaciones de mis servidores.
El proceso es el siguiente:
Instalar el paquete (no pide dependencias)
#aptitude install cron-apt

Por defecto, introduce una línea en el fichero /etc/cron.d/cron-apt para que busque las actualizaciones a las 4am todas las noches.

Ahora a editar el fichero de configuración:
#vi /etc/cron-apt/config

Básicamente hay que modificar las siguientes lineas:
MAILTO="micorreo@miservidor.com"
MAILON="upgrade"

También podemos modificar la siguiente línea:
APTCOMMAND=/usr/bin/aptitude

Para que utilice aptitude en lugar de apt-get.