Volver a la lista

Entrada y salida estándar — Redirección de stdin/stdout

Comprender los flujos de entrada/salida/error estándar de Python y aprender a utilizar la redirección y las tuberías en la terminal.

Intermedio
|
10min
|
Verificado (2026-07)
entrada/salida estándarstdinstdoutstderrredirecciónCLI
Progreso0/18 (0%)

Entrada y salida estándar — Redirección de stdin/stdout

Al finalizar este tema

Podrás explicar las funciones de stdin, stdout y stderr, y conectar la entrada y salida de programas mediante redirección (>, <) y tuberías (|) en la terminal.


Tres canales

Cuando se ejecuta un programa, el sistema operativo abre automáticamente tres canales:

NombreDirecciónUsoPython
stdin (entrada estándar)Externo → ProgramaEntrada del tecladoinput(), sys.stdin
stdout (salida estándar)Programa → ExternoResultado normalprint(), sys.stdout
stderr (error estándar)Programa → ExternoErrores/advertenciassys.stderr

Por defecto, stdin está conectado al teclado y stdout y stderr a la pantalla (terminal).


print() escribe en stdout

python
# hello.py
print("Hola") # salida a stdout
bash
$ python hello.py
Hola

print() llama internamente a sys.stdout.write(). También se puede usar directamente:

python
import sys
sys.stdout.write("salida a stdout\n")
sys.stderr.write("salida a stderr\n")

Ambas líneas aparecen en la pantalla, pero a través de canales diferentes. Esta diferencia se manifiesta en la redirección.


Redirección — canalizar a un archivo

En la terminal, > y < permiten cambiar la dirección de entrada/salida.

stdout a un archivo (>)

bash
$ python hello.py > output.txt

No se muestra nada en la pantalla. El resultado de print() se guarda en el archivo output.txt.

bash
$ cat output.txt
Hola

>> continúa el contenido anterior:

bash
$ python hello.py >> output.txt # agregar al final del contenido existente

Entrada estándar desde un archivo (<)

python
# count.py
import sys
lines = sys.stdin.readlines()
print(f"Total {len(lines)} líneas")
bash
$ python count.py < data.txt
Total 42 líneas

El contenido de data.txt se ingresa a través de stdin en lugar de la entrada del teclado.

Separar solo stderr

python
# process.py
import sys
print("Resultado del procesamiento: éxito")
sys.stderr.write("Advertencia: algunos datos faltan\n")
bash
$ python process.py > result.txt 2> error.txt

> redirige únicamente la salida estándar (stdout), mientras que 2> redirige únicamente la salida de error estándar (stderr). Esto permite separar los resultados y los errores en archivos distintos.


Tubería — Conectar programas

| (tubería) conecta la salida estándar (stdout) del programa anterior con la entrada estándar (stdin) del programa siguiente:

bash
$ cat data.csv | python process.py | python report.py > final.txt
text
cat → (stdout) → | → (stdin) → process.py → (stdout) → | → (stdin) → report.py → final.txt

Cada programa recibe y procesa únicamente los datos que provienen de su entrada inmediata, y luego transfiere el resultado al siguiente paso. Este es el principio fundamental de la filosofía Unix, que consiste en combinar programas pequeños para realizar tareas complejas.


Lectura línea por línea desde stdin en Python

python
# upper.py — Convierte la entrada a mayúsculas
import sys
for line in sys.stdin:
print(line.strip().upper())
bash
$ echo "hello world" | python upper.py
HELLO WORLD
$ cat names.txt | python upper.py
ALICE
BOB
CHARLIE

sys.stdin es iterable. Al leerlo línea por línea con un bucle for, se utiliza la memoria de manera eficiente.


La relación entre input() y stdin

python
name = input("Nombre: ") # Prompt → stderr? No, stdout

input() internamente:

  1. imprime la cadena de entrada en stdout
  2. lee una línea desde stdin y la devuelve

Por lo tanto, se debe tener cuidado al usarlo con tuberías (pipes):

bash
$ echo "Cheolsu" | python -c "name = input(); print(f'Hola, {name}')"
Hola, Cheolsu

En Pipe, los prompts carecen de significado; por lo tanto, al crear herramientas CLI, es preferible leer directamente sys.stdin en lugar de input().


Ejemplos de uso práctico

python
# csv_filter.py — Imprime solo las filas que cumplen una condición específica
import sys
import csv
reader = csv.reader(sys.stdin)
header = next(reader)
print(",".join(header))
for row in reader:
if float(row[2]) > 100: # La tercera columna es mayor que 100
print(",".join(row))
bash
$ cat sales.csv | python csv_filter.py > filtered.csv

El uso de stdin/stdout permite evitar codificar nombres de archivos en el código. Al poder conectar cualquier archivo mediante tuberías, se incrementa la reutilización del código.


Encadenamiento de tuberías — Filosofía UNIX

bash
# Busca solo ERROR en los registros y ordénalos por frecuencia
$ cat server.log | grep "ERROR" | sort | uniq -c | sort -rn | head -5

Cada programa realiza una sola tarea de manera eficiente y se conecta mediante tuberías (pipes). Los scripts de Python también pueden formar parte de esta cadena:

python
# word_count.py — Calcula la frecuencia de palabras
import sys
from collections import Counter
words = []
for line in sys.stdin:
words.extend(line.strip().split())
for word, count in Counter(words).most_common(10):
print(f"{count:>5} {word}")
bash
$ cat article.txt | python word_count.py
42 the
31 and
28 to

Mostrar el progreso mediante stderr

python
import sys
total = 1000
for i in range(total):
# Lógica de procesamiento...
if i % 100 == 0:
print(f'Progreso: {i}/{total}', file=sys.stderr)
print(f'Resultado: {i * 2}') # Salida real → stdout
bash
$ python process.py > results.txt
Progreso: 0/1000 ← Visible en la pantalla (stderr)
Progreso: 100/1000
...

La salida estándar (stdout) se redirige a un archivo y se guarda en results.txt, mientras que la salida de error estándar (stderr) sigue mostrándose en la pantalla. Este es un patrón práctico para separar los mensajes de progreso de los datos resultantes.


Resumen clave

SintaxisSignificado
>stdout a archivo (sobrescribir)
>>stdout a archivo (añadir al final)
<archivo como entrada estándar (stdin)
2>stderr a archivo
|stdout → stdin del siguiente programa
2>&1fusionar stderr con stdout

/dev/null — Descartar la salida

bash
# Descartar stdout (solo ver errores)
$ python noisy_script.py > /dev/null
# Descartar stderr (solo ver resultados)
$ python noisy_script.py 2> /dev/null
# Descartar ambos (silencio total)
$ python noisy_script.py > /dev/null 2>&1

/dev/null es el "papelera". Se utiliza para suprimir la salida innecesaria en scripts automatizados.

python
# El mismo patrón en Python
import os, sys
if os.environ.get("QUIET"):
sys.stdout = open(os.devnull, "w")

subprocess — Configuración de tuberías en Python

python
import subprocess
# Ejecutar comando externo + capturar stdout
result = subprocess.run(
["ls", "-la"],
capture_output=True,
text=True
)
print(result.stdout)
print(result.stderr)
# Encadenamiento de tuberías
p1 = subprocess.Popen(["cat", "data.txt"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "ERROR"], stdin=p1.stdout, stdout=subprocess.PIPE)
output = p2.communicate()[0].decode()

En Python, es posible conectar programáticamente la entrada estándar (stdin) y la salida estándar (stdout) de un comando del shell.


print() corresponde a stdout, mientras que los mensajes de error van a stderr. Comprender esta separación hace que la redirección y el uso de tuberías resulten más naturales.

💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...