En el mundo de la interfaz de línea de comandos, los programas suelen interactuar con tres flujos de datos estándar:
stdin): donde un programa recibe su entrada (normalmente desde el teclado).stdout): donde un programa envía su salida normal (normalmente a la pantalla de la terminal).stderr): donde un programa envía los mensajes de error (normalmente a la pantalla de la terminal).Recuerda que los presentamos en el capítulo Tuberías y listas de comandos.
Las tuberías pueden considerarse una forma de redirección: la salida estándar de un programa se envía directamente a la entrada estándar de otro. Ya hemos visto las tuberías. Este concepto tratará la redirección desde y hacia archivos.
La redirección del shell es un mecanismo potente que te permite cambiar el destino de estos flujos. En lugar de que un programa lea del teclado o escriba en la pantalla, puedes redirigir la entrada desde un archivo o enviar la salida a un archivo. Esto proporciona una flexibilidad y un control considerables sobre cómo interactúan los programas con los datos.
Estos son los operadores de redirección más comunes y lo que hacen:
> (Redirección de salida)Propósito: redirigir la salida estándar (stdout) de un comando a un archivo.
Comportamiento:
Ejemplo:
# Sends the output of 'ls -l' to 'file_listing.txt'
ls -l > file_listing.txt
La redirección se realiza antes de que se ejecute el comando. Esto significa que no puedes redirigir al mismo archivo desde el que necesitas leer.
date > date.txt # populate the file with the current date
cat date.txt > date.txt # 'date.txt' is now empty!
En el segundo comando del ejemplo anterior,
>> (Redirección de salida para añadir)Propósito: añadir la salida estándar (stdout) de un comando a un archivo.
Comportamiento:
Ejemplo:
# Adds "Another line" to the end of the file
echo "Another line" >> file_listing.txt
< (Redirección de entrada)Propósito: redirigir la entrada estándar (stdin) de un comando desde un archivo.
Comportamiento: el comando lee su entrada desde el archivo especificado en lugar del teclado.
Ejemplo:
# 'tr' reads from 'lowercase.txt' and
# output is redirected to 'uppercase.txt'
tr 'a-z' 'A-Z' < lowercase.txt > uppercase.txt
2> (Redirección de errores):stderr) de un comando a un archivo.# Error message from 'rm' is sent to 'error_log.txt'
rm non_existent_file 2> error_log.txt
Puedes añadir el error estándar a un archivo con 2>>.
También hay redirecciones que pueden combinar tanto stdin como stderr.
Consulta el manual para más detalles.
/dev/null/dev/null es un archivo especial que
A veces se le llama «el cubo de bits». Es útil para suprimir la salida o los errores.
some_command > /dev/null # Discards stdout
some_command 2> /dev/null # Discards stderr
# Using /dev/null as input will prevent the command
# from reading data from the keyboard
some_command < /dev/null
Se pueden proporcionar varias redirecciones a la vez.
some_command < input.txt > output.txt 2> error.txt
Se puede copiar una redirección.
# send stderr to the same destination as stdout
some_command > output.txt 2>&1
Cuando veas 2>&1, léelo como «redirige stderr a lo que stdout esté apuntando actualmente».
Bash procesa las instrucciones de redirección estrictamente de izquierda a derecha, lo que significa que puedes hacer:
# redirect stdout to 'output1.txt'
# redirect stderr to the same place
# then change stdout to 'output2.txt'
some_command > output1.txt 2>&1 > output2.txt
En el contexto de la programación de shell y de sistemas operativos como Linux/Unix, un descriptor de archivo (FD) es un número entero no negativo que sirve como identificador o referencia para un archivo abierto o un recurso de E/S (entrada/salida). Piensa en él como una etiqueta o un número de referencia que el sistema operativo utiliza para hacer un seguimiento de los archivos abiertos y los flujos de datos.
Los números que ves en el lado izquierdo de las redirecciones son descriptores de archivo.
A los flujos de E/S estándar se les asignan los 3 primeros descriptores de archivo:
Se pueden establecer o crear nuevos descriptores de archivo con el comando exec y los operadores de redirección.
# create FD 3 as a copy of stdout
exec 3>&1
# send stdout to a log file
exec > log.txt
# then redirect both stdout and file descriptor 3
echo "some debug message" >&3 # displayed in the terminal
some_command 2>&1 # stdout and stderr send to 'log.txt'
Esta técnica parece bastante enrevesada, pero puede resultar muy útil en situaciones en las que algún otro paquete de software ejecuta tu script y la salida estándar es capturada automáticamente por dicho software.
El comando bats que se utiliza para ejecutar las pruebas unitarias de este track funciona así: bats captura la salida estándar y el error estándar de una prueba, pero los mensajes de depuración enviados al FD 3 se mostrarán en la terminal.
¿Por qué es útil la redirección?
Las redirecciones del shell te dan un control detallado sobre cómo interactúan los programas con los datos, lo que te permite crear flujos de trabajo complejos y gestionar la información de forma eficaz.