Tracks
/
Bash
Bash
/
Temario
/
Redirección
Re

Redirección en Bash

{one: "1 ejercicio", many: "%{count} de ejercicios", other: "%{count} ejercicios"}

Acerca de Redirección

En el mundo de la interfaz de línea de comandos, los programas suelen interactuar con tres flujos de datos estándar:

  1. Entrada estándar (stdin): de dónde recibe un programa su entrada (normalmente del teclado).
  2. Salida estándar (stdout): a dónde envía un programa su salida normal (normalmente a la pantalla de la terminal).
  3. Error estándar (stderr): a dónde envía un programa sus mensajes de error (normalmente a la pantalla de la terminal).

Recuerda que presentamos estos tres flujos en el capítulo Pipelines y listas de comandos.

Note

Un pipeline se puede considerar una forma de redirección: la salida estándar de un programa se envía directamente a la entrada estándar de otro. Ya vimos los pipelines. En este concepto veremos cómo redirigir desde archivos y hacia archivos.

La redirección del shell es un mecanismo poderoso 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 te da bastante flexibilidad y control sobre cómo los programas interactúan con los datos.

Operadores de redirección principales

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:

    • Si el archivo no existe, se crea.
    • Si el archivo existe, su contenido se sobrescribe.
  • Ejemplo:

    # Sends the output of 'ls -l' to 'file_listing.txt'
    ls -l > file_listing.txt
    
Caution

La redirección se hace antes de que se ejecute el comando. Esto significa que no puedes redirigir hacia el mismo archivo del 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,

  1. Bash primero trunca el archivo indicado en la redirección. Esto destruye el contenido anterior y deja un archivo vacío.
  2. Luego bash lee el archivo que acaba de quedar vacío.
  3. Después bash escribe el contenido (es decir, nada) de vuelta en el archivo.

>> (redirección de salida con adición)

  • Propósito: agregar la salida estándar (stdout) de un comando al final de un archivo.

  • Comportamiento:

    • Si el archivo no existe, se crea.
    • Si el archivo existe, la salida se agrega al final del archivo.
  • 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 del archivo indicado 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):

  • Propósito: redirigir el error estándar (stderr) de un comando a un archivo.
  • Comportamiento: los mensajes de error se envían al archivo indicado en lugar de a la terminal.
  • Ejemplo:
    # Error message from 'rm' is sent to 'error_log.txt'
    rm non_existent_file 2> error_log.txt
    

Puedes agregar el error estándar a un archivo con 2>>.

Otras redirecciones

También hay redirecciones que pueden combinar stdin y stderr. Consulta el manual para más detalles.

/dev/null

/dev/null es un archivo especial que

  • es un archivo vacío cuando lees de él, y
  • descarta todos los datos que se escriben en él.

A veces se le llama «el bitbucket». 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

Combinar redirecciones

Puedes dar varias redirecciones a la vez.

some_command < input.txt > output.txt 2> error.txt

Una redirección se puede copiar.

# send stderr to the same destination as stdout
some_command > output.txt 2>&1

Cuando veas 2>&1, léelo como «redirige el error estándar a lo que sea a lo que la salida estándar esté apuntando en ese momento». Bash procesa las instrucciones de redirección estrictamente de izquierda a derecha, lo que significa que puedes hacer esto:

# 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
Advanced

Descriptores de archivo

En el contexto de la programación del 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 de un archivo abierto o de un recurso de E/S (entrada/salida). Piénsalo como una etiqueta o un número de referencia que el sistema operativo usa para llevar la cuenta de los archivos abiertos y los flujos de datos.

Los números que ves a la izquierda de las redirecciones son descriptores de archivo.

A los flujos de E/S estándar se les asignan los 3 primeros descriptores de archivo:

  • la entrada estándar es el FD 0
  • la salida estándar es el FD 1
  • el error estándar es el FD 2

Puedes 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 ser muy útil cuando tu script lo ejecuta otro paquete de software y ese software captura automáticamente la salida estándar. El comando bats, que se usa para ejecutar las pruebas unitarias de este track, funciona así: bats captura el stdout y el stderr de una prueba, pero los mensajes de depuración enviados al FD 3 se muestran en la terminal.

En resumen

¿Por qué es útil la redirección?

  • Guardar la salida: almacena los resultados de un comando para revisarlos o procesarlos después.
  • Registro: captura los mensajes de error para depurarlos.
  • Automatización: encadena comandos, usando la salida de uno como la entrada de otro.
  • Filtrado: descarta la salida que no necesitas.
  • Procesamiento por lotes: procesa datos de archivos en lugar de escribirlos a mano.
  • Scripts: las redirecciones son esenciales para escribir scripts de shell robustos.

Las redirecciones del shell te dan un control detallado sobre cómo los programas interactúan con los datos, y te permiten construir flujos de trabajo complejos y gestionar la información de forma eficaz.

Editar en GitHub El enlace se abre en una ventana o pestaña nueva