tee
Muestra la salida de un comando y a la vez la guarda en un archivo.
Escribe lo que recibe en la pantalla y, al mismo tiempo, en un archivo. Lo usas para ver el resultado de un comando y guardarlo sin correrlo dos veces, y también para escribir en archivos que pertenecen a root, algo que la redirección > no puede hacer. Viene incluido en coreutils, así que ya está instalado en Debian y Ubuntu.
tee [opciones] [ARCHIVO]...tee borra el contenido del archivo en cuanto lo abre: sin la opción -a, lo que había queda sustituido por la salida del comando, y si el comando no produce nada te quedas con el archivo vacío. Eso se nota mucho cuando el archivo es un /etc/ssh/sshd_config o cualquier otra configuración del sistema. Usa -a para agregar al final y revisa con head lo que escribiste.
Despiece
6 ejemplosCrear un archivo con una línea
| N.º | Pieza | Tipo | Qué hace |
|---|---|---|---|
| 1 | echo | Comando | Imprime el texto en la salida estándar. |
| 2 | "hola" | Argumento | Lo que se imprime; las comillas protegen el texto de la terminal. |
| 3 | | | Operador | El pipe: manda lo que imprime echo a la entrada de tee. |
| 4 | tee | Comando | Muestra lo que recibe y lo copia al archivo que sigue. |
| 5 | saludo.txt | Argumento | El archivo que se crea (o se sobrescribe) de inmediato. |
saludo.txt queda con la palabra hola, y además la ves en pantalla. Es la forma más simple de crear un archivo de texto sin abrir nano ni vim, aunque también la más fácil de olvidar: el archivo se escribe al instante.
Ver la salida y guardarla al mismo tiempo
| N.º | Pieza | Tipo | Qué hace |
|---|---|---|---|
| 1 | df | Comando | Muestra el espacio usado y libre de cada disco y partición. |
| 2 | -h | Opción | Human readable: muestra los tamaños en GB y MB en vez de bloques de 1024. |
| 3 | | | Operador | Pasa la tabla que imprime df a la entrada de tee. |
| 4 | tee | Comando | Escribe lo que recibe tanto en pantalla como en el archivo. |
| 5 | disco.txt | Argumento | El archivo donde queda guardada la tabla. |
Ves el estado de tus discos y además queda un registro en disco.txt. El > (df -h > disco.txt) también guarda, pero no muestra nada: con tee no pierdes de vista la salida, y eso es justo lo que hace útil.
Agregar al final sin borrar lo anterior
| N.º | Pieza | Tipo | Qué hace |
|---|---|---|---|
| 1 | uname | Comando | Muestra información del kernel: versión, arquitectura y nombre del equipo. |
| 2 | -a | Opción | Imprime toda la información del sistema, no solo el nombre del núcleo. |
| 3 | | | Operador | Pasa esa información a tee. |
| 4 | tee | Comando | Escribe en pantalla y en el archivo. |
| 5 | -a | Opción | Append: agrega al final en vez de sobrescribir el archivo. |
| 6 | sistema.txt | Argumento | El archivo que se va llenando línea por línea. |
Cada corrida agrega una línea más a sistema.txt, así que sirve como bitácora: con el tiempo tienes el registro de cómo estaba el equipo. Sin la a, tee sobrescribe el archivo y en sistema.txt solo queda lo de la última vez.
Escribir en dos archivos de una vez
| N.º | Pieza | Tipo | Qué hace |
|---|---|---|---|
| 1 | ls | Comando | Lista el contenido de la carpeta. |
| 2 | -l | Opción | Listado largo, con permisos, dueño, tamaño y fecha. |
| 3 | | | Operador | Pasa el listado a tee. |
| 4 | tee | Comando | Escribe lo mismo en cada archivo que le indiques. |
| 5 | lista.txt | Argumento | Primer archivo de salida. |
| 6 | lista2.txt | Argumento | Segundo archivo de salida; tee acepta los que le pases. |
Los dos archivos quedan idénticos con el contenido de ls -l. Te sirve para dejar una copia en la carpeta del proyecto y otra en un USB, o para guardar el resultado en un archivo y en un log del sistema.
Guardar solo la parte que te interesa
| N.º | Pieza | Tipo | Qué hace |
|---|---|---|---|
| 1 | ps | Comando | Muestra los procesos que están corriendo. |
| 2 | aux | Argumento | Formato que muestra todos los procesos de todos los usuarios, con CPU y memoria. |
| 3 | | | Operador | Primer pipe: la lista de procesos pasa a head. |
| 4 | head | Comando | Deja pasar solo las primeras líneas. |
| 5 | -20 | Opción | Las primeras 20 líneas, que es justo lo que cabe en una pantalla. |
| 6 | | | Operador | Segundo pipe: lo que dejó pasar el filtro llega a tee. |
| 7 | tee | Comando | Está al final del pipe a propósito: así guarda lo que pasó el filtro, no todo. |
| 8 | procesos.txt | Argumento | El archivo con los 20 primeros procesos. |
procesos.txt queda con los primeros 20 procesos y también los ves en pantalla. Por eso tee se escribe al final de la cadena: si lo pusieras al principio, guardaría la lista completa antes de que head la recorte.
Escribir en un archivo que pertenece a root
| N.º | Pieza | Tipo | Qué hace |
|---|---|---|---|
| 1 | echo | Comando | Imprime la línea que quieres agregar. |
| 2 | "127.0.0.1 www.miapp.local" | Argumento | La línea: una IP y el nombre de tu app local. |
| 3 | | | Operador | Pasa esa línea a tee. |
| 4 | sudo | Comando | Ejecuta lo que sigue como root, que es quien puede escribir en /etc. |
| 5 | tee | Comando | Quien abre y escribe el archivo de verdad. |
| 6 | -a | Opción | Agrega al final: no borra las demás reglas de /etc/hosts. |
| 7 | /etc/hosts | Argumento | El archivo del sistema que quieres modificar. |
La línea queda en /etc/hosts con permisos de root. Esto es justo para lo que existe tee: con sudo echo "..." > /etc/hosts la redirección la hace tu shell normal y sales con Permission denied, porque el > se ejecuta antes de que sudo entre en juego.
Opciones
Las que sí vas a usar| Opción | Qué hace |
|---|---|
| -a--append | Agrega al final del archivo en vez de sobrescribirlo. Es la que más se usa: sin -a, tee vacía el archivo cada vez que corre. |
| -i--ignore-interrupts | Ignora el Ctrl-C. Útil dentro de un bucle largo, donde no quieres que una interrupción te deje el archivo a medio escribir. |
| -p | Si el programa que lee la salida se cierra antes de tiempo (un pipe roto), tee sigue escribiendo en los archivos en vez de detenerse. |
| --output-error=MODE | Qué hace cuando no puede escribir en un archivo: warn (avisa y sigue), warn-nopipe, exit (aborta con código de salida 1) o exit-nopipe. |
Fallas comunes
| Falla | Remedio |
|---|---|
| Confundir tee con la redirección >. | No son lo mismo. El > guarda la salida y no muestra nada: ls > lista.txt no imprime nada en pantalla. tee hace las dos cosas, por eso siempre va con un pipe delante. En un script donde no quieres ver la salida, usa > y reserva tee para cuando sí te sirve verla. |
| Olvidar la -a y perder lo que ya estaba en el archivo. | tee abre el archivo en modo sobrescribir desde el primer instante, así que sin -a queda solo la salida de la última corrida, e incluso queda vacío si el comando no produjo nada. Para ir anotando poco a poco usa tee -a, y compruébalo con wc -l antes y después. |
| Escribir sudo echo "texto" > /etc/archivo y obtener Permission denied. | El > lo ejecuta tu shell, no sudo, así que el archivo se intenta abrir con tus permisos y falla. La solución es mover la redirección a un pipe: echo "texto" | sudo tee -a /etc/archivo. Ahí el sudo sí protege a tee, porque tee es el que abre el archivo. |
| Usar sudo tee y llenar la pantalla con lo que se escribió. | tee siempre repite en pantalla lo que guarda. Si no quieres verlo, manda esa copia a la basura: echo "texto" | sudo tee -a /etc/archivo > /dev/null. |
Preguntas frecuentes
- ¿Para qué sirve tee si ya existe la redirección >?
- El > guarda la salida y no la muestra; tee la muestra y también la guarda. Esa diferencia importa cuando el comando produce mucho texto y quieres verlo mientras se genera, o cuando necesitas ver una parte y guardar el resto. tee también resuelve el caso de escribir en archivos de root, porque el sudo va antes de tee y no antes del >.
- ¿Cuál es la diferencia entre tee y >?
- Con > (df -h > disco.txt) el archivo se escribe y no ves nada en pantalla. Con tee (df -h | tee disco.txt) se escribe igual, pero además ves la salida. tee va después de un pipe; > va al final del comando.
- ¿Cómo agrego una línea al final de un archivo sin borrarlo?
- Con los dos signos mayor que: echo "texto" >> archivo.txt. Si necesitas ver lo que agregas, la versión con tee es echo "texto" | tee -a archivo.txt, donde la -a (append) hace lo mismo que el >>. Sin esa a, tee sobrescribe el archivo completo.
- ¿Por qué sudo echo x > /etc/archivo no funciona?
- Porque el > lo procesa tu shell, que sigue corriendo como usuario normal, e intenta abrir el archivo de root antes de que sudo haga nada. Sales con Permission denied. La forma correcta es echo "x" | sudo tee -a /etc/archivo: así el sudo protege a tee, que es quien abre el archivo.
- ¿Cómo guardo la salida de un comando en varios archivos a la vez?
- Pásale varios archivos a tee: ls -l | tee lista.txt lista2.txt. Todos reciben la misma salida. Si lo que quieres es versiones distintas del mismo comando, mejor guardarlo una vez y luego copiarlo con cp hacia los otros destinos.
Ver también
Muestra el contenido de uno o varios archivos.
36sortOrdena líneas de texto alfabética o numéricamente.
40uniqQuita o cuenta líneas repetidas que están una seguida de otra.
42wcCuenta las líneas, palabras y bytes de un archivo o de la salida de otro comando.
29echoMuestra texto en la terminal o lo guarda en un archivo.