file descriptors (ii de ii)

3 de julio de 2009

Hasta ahora no hemos hablado para nada de la salida estandard STDERR. Este tipo de salida es utilizada por los procesos para mostrar los errores o para trabajos de diagnóstico. Como mencioné en el primer post la STDIN y la STDERR se muestran por el terminal. La información "buena" del proceso y la información de error se entremezclan.

Supongamos que tenemos un proceso el cual es susceptible de producir errores. Supongamos también que se lanza cada día en un cron de la siguiente forma:

# miproceso > /var/log/miproceso.log

Aparentemente, el proceso cada día se ejecutará y almacena su resultado dentro de /var/log/miproceso.log. No es correcto del todo. Dentro del miproceso.log solo encontraremos el resultado de la STDOUT de miproceso, pero no los errores que se hayan producido. Es decir, el resultado legitimo del programa lo hemos redireccionado a un fichero, pero los errores se siguen mostrando por el terminal. Para solucionar esto, tenemos que redidireccionar la STDOUT y la STDERR con la siguiente sintaxis:
# miproceso > /var/log/miproceso.log 2>&1

Le estamos diciendo que la STDERR (o file descriptor 2) se redireccione al mismo sitio donde esta redireccionado la STDOUT (o file descriptor 1).

También es posible redireccionar cada salida a un archivo diferente. Es decir que los resultados vayan a un log y los errores a otro log:
# miproceso 1> /var/log/resultado.log
# miproceso 2> /var/log/errores.log

Veamos un ejemplo real de la existencia y del funcionamiento de STDERR. Supongamos que tenemos un archivo llamado "pepe.txt" que no existe. Si intentamos ver su contenido se producirá un mensaje de error. Este mensaje de error, aunque haya gente que cree lo contrario, lo vemos por pantalla pero no viene de la STDOUT. Viene de la STDERR. Redireccionemos los errores del comando cat a un fichero de log.
# cat pepe.txt
cat: pepe.txt: No existe el fichero ó directorio
# cat pepe.txt 2>error.log
# cat error.log
cat: pepe.txt: No existe el fichero ó directorio

Otro ejemplo muy utilizado de los redirectores es utilizarlo junto con el dispositivo null. El dispositivo /dev/null es un dispositivo que todo lo que enviemos se perderá en el infinito. Pensémoslo como un dispositivo papelera. Se utiliza mucho cuando queremos ejecutar un proceso y no queremos almacenar nada de su resultado. Es decir, no queremos que muestre nada por el terminal:
# miproceso > /dev/null 2>&1

Tanto la STDOUT como la STDERR las envio a la papelera.

Un comando muy utilizado junto con las pipe es el comando de Linux tee. Si utilizamos un redirector hacia un archivo, el problema que tenemos es que ya no veremos nada por el terminal. Si lo que queremos es redireccionar y al mismo tiempo ver por el terminal debemos utilizar un tee:
# cat /etc/passwd | grep root | tee resultado.txt | less
root:x:0:0:root:/root:/bin/bash
# cat resultado.txt 
root:x:0:0:root:/root:/bin/bash

El comando tee recibe por su STDIN unos datos que los almacena en resultado.txt y al mismo tiempo los manda por su STDOUT lo que posibilita que los veamos por el terminal.

No solo Linux/UNIX dispone de esta potencia en sus shells. Windows con la aparición de la Windows Power Shell también dispone de todas estas funciones.