Cómo redirigir la salida a un archivo y stdout

En bash, llamando foo mostraría cualquier salida de ese comando en la salida estándar.

llamar foo > output redirigiría cualquier salida de ese comando al archivo especificado (en este caso, 'salida').

¿Hay alguna forma de redirigir la salida a un archivo? y ¿Se muestra en stdout?

preguntado el 06 de enero de 09 a las 23:01

Si alguien acaba de terminar aquí buscando capturar la salida de error en un archivo, eche un vistazo a: unix.stackexchange.com/questions/132511/… -

Una nota sobre terminología: cuando ejecuta foo > output los datos is escrito en stdout y stdout is el archivo llamado output. Es decir, escribiendo en el archivo is escribiendo en stdout. Estás preguntando si es posible escribir tanto en stdout como en la terminal. -

@WilliamPursell No estoy seguro de que tu aclaración mejore las cosas :-) ¿Qué tal esto? OP pregunta si es posible dirigir el llamado programa stdout a un archivo y al programa de llamadas stdout (el último es el stdout que el programa llamado heredaría si no se hiciera nada especial; es decir, el terminal, si el programa que llama es una sesión de bash interactiva). Y tal vez también quieran dirigir el programa llamado stderr de manera similar ("cualquier resultado de ese comando" podría interpretarse razonablemente en el sentido de incluir stderr). -

10 Respuestas

El comando que quieres se llama tee:

foo | tee output.file

Por ejemplo, si solo te importa stdout:

ls -a | tee output.file

Si desea incluir stderr, haga lo siguiente:

program [arguments...] 2>&1 | tee outfile

2>&1 redirige el canal 2 (stderr / error estándar) al canal 1 (stdout / salida estándar), de modo que ambos se escriben como stdout. También se dirige al archivo de salida dado a partir del tee mando.

Además, si quieres anexar al archivo de registro, use tee -a como:

program [arguments...] 2>&1 | tee -a outfile

Respondido 23 Oct 17, 18:10

Si OP quiere que se redirija "toda la salida", también deberá tomar stderr: "ls -lR / 2> & 1 | tee output.file" - James Brady

@evanmcdonnal La respuesta no es incorrecta, es posible que no sea lo suficientemente específica o completa según sus requisitos. Ciertamente, existen condiciones en las que es posible que no desee que stderr como parte de la salida se guarde en un archivo. Cuando respondí esto hace 5 años, asumí que el OP solo quería stdout, ya que mencionó stdout en el tema de la publicación. - Zoredache

Ah, lo siento, podría haber estado un poco confundido. Cuando lo probé, simplemente no obtuve ningún resultado, tal vez todo iba a stderr. - evanmcdonnal

Utiliza -a argumento sobre tee para agregar contenido a output.file, en lugar de sobrescribirlo: ls -lR / | tee -a output.file - juez

Si estás usando $? luego devolverá el código de estado de tee, que probablemente no sea lo que desea. En su lugar, puede utilizar ${PIPESTATUS[0]}. - La Goutte

$ program [arguments...] 2>&1 | tee outfile

2>&1 vuelca los flujos stderr y stdout. tee outfile toma la secuencia que obtiene y la escribe en la pantalla y en el archivo "outfile".

Esto es probablemente lo que busca la mayoría de la gente. La situación probable es que algún programa o script esté trabajando duro durante mucho tiempo y produciendo una gran cantidad de resultados. El usuario desea verificarlo periódicamente para ver el progreso, pero también desea que la salida se escriba en un archivo.

El problema (especialmente cuando se mezclan flujos stdout y stderr) es que se depende de que el programa elimine los flujos. Si, por ejemplo, todas las escrituras en stdout son no enrojecido, pero todas las escrituras a stderr se encuentran las enrojecidos, terminarán fuera de orden cronológico en el archivo de salida y en la pantalla.

También es malo si el programa solo genera 1 o 2 líneas cada pocos minutos para informar el progreso. En tal caso, si el programa no eliminara la salida, el usuario ni siquiera vería ninguna salida en la pantalla durante horas, porque ninguna de ellas pasaría por la tubería durante horas.

Actualización: el programa unbuffer, Parte de la expect paquete, resolverá el problema de almacenamiento en búfer. Esto hará que stdout y stderr escriban en la pantalla y el archivo inmediatamente y los mantengan sincronizados cuando se combinan y se redirigen a tee. P.ej:

$ unbuffer program [arguments...] 2>&1 | tee outfile

contestado el 22 de mayo de 14 a las 04:05

¿Alguien sabe de un 'unbuffer' para osx? - Juan Mee

Si no puede usar unbuffer, GNU coreutils incluye una herramienta llamada estándar que se puede utilizar para evitar el almacenamiento en búfer de salida como tal $ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile - Peter

Si está usando OS X, es un poco más fácil usar unbuffer en la mayoría de los casos, aunque no si desea pasar señales al comando que está ejecutando. Mi comentario estaba más dirigido a usuarios que están en Linux, donde es más probable que coreutils esté instalado de forma predeterminada. @ Ethan, vea esta respuesta si está confundido acerca de la sintaxis stdbuf: stackoverflow.com/a/25548995/942781 - Peter

Tenga en cuenta que python tiene una opción incorporada -u que anula el búfer de salida. - fabian789

Un salvavidas absoluto para entrenar modelos de aprendizaje automático en los que quiero iniciar sesión sin código adicional, pero también ver el resultado durante las horas / días que se necesitan para ejecutar, ¡gracias! - rococó

Otra forma que funciona para mí es,

<command> |& tee  <outputFile>

como se muestra en manual de bash gnu

Ejemplo:

ls |& tee files.txt

Si se usa '| &', command1's Error estándar, además de su salida estándar, está conectado a la entrada estándar de command2 a través de la tubería; es taquigrafía para 2> & 1 |. Esta redirección implícita del error estándar a la salida estándar se realiza después de cualquier redirección especificada por el comando.

Para obtener más información, consulte redirección

respondido 18 mar '17, 23:03

Si estás usando $? luego devolverá el código de estado de tee, que probablemente no sea lo que desea. En su lugar, puede utilizar ${PIPESTATUS[0]}. - La Goutte

Este método descarta la salida de la consola en color, ¿alguna idea? - shakram02

Pruebe: unbuffer ls -l --color = auto | tee files.txt - Luciano Andrés Martini

Puede utilizar principalmente Zoredache solución, pero si no desea sobrescribir el archivo de salida, debe escribir tee con la opción -a de la siguiente manera:

ls -lR / | tee -a output.file

contestado el 23 de mayo de 17 a las 13:05

Algo para agregar ...

El paquete unbuffer tiene problemas de soporte con algunos paquetes en las versiones de fedora y redhat unix.

Dejando a un lado los problemas

Seguir funcionó para mí

bash myscript.sh 2>&1 | tee output.log

¡Gracias ScDF & Mateo tus aportaciones me ahorraron mucho tiempo ..

contestado el 23 de mayo de 17 a las 12:05

Usar tail -f output Deberia trabajar.

Respondido 19 Abr '20, 14:04

Respuesta de bonificación ya que este caso de uso me trajo aquí:

En el caso de que necesite hacer esto como algún otro usuario

echo "some output" | sudo -u some_user tee /some/path/some_file

Tenga en cuenta que el eco se producirá a medida que usted y la escritura del archivo ocurrirá como "some_user", lo que sucederá NO El trabajo es si tuviera que ejecutar el eco como "algún_usuario" y redirigir la salida con >> "algún_archivo" porque la redirección del archivo sucederá como usted.

Sugerencia: tee también admite agregar con el indicador -a, si necesita reemplazar una línea en un archivo como otro usuario, puede ejecutar sed como el usuario deseado.

Respondido 20 Jul 17, 17:07

Puede hacer eso para todo su script usando algo como eso al principio de su script:

#!/usr/bin/env bash

test x$1 = x$'\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0 $'\x00' "$@" ) | tee mylogfile ; exit $? ; }

# do whaetever you want

Esto redirige las salidas stderr y stdout al archivo llamado mylogfile y deja que todo salga a la normalidad al mismo tiempo.

Se utilizan algunos trucos estúpidos:

  • utilizado exec sin comando para configurar redirecciones,
  • utilizado tee para duplicar salidas,
  • reinicia el script con las redirecciones deseadas,
  • utilizar un primer parámetro especial (un simple NUL carácter especificado por el $'string' notación bash especial) para especificar que el script se reinicia (su trabajo original no puede usar ningún parámetro equivalente),
  • intente conservar el estado de salida original al reiniciar el script utilizando el pipefail .

Feo pero útil para mí en determinadas situaciones.

contestado el 03 de mayo de 19 a las 11:05

< command > |& tee filename # esto creará un archivo "nombre de archivo" con el estado del comando como contenido. Si un archivo ya existe, eliminará el contenido existente y escribirá el estado del comando.

< command > | tee >> filename # esto agregará el estado al archivo pero no imprime el estado del comando en standard_output (pantalla).

Quiero imprimir algo usando "echo" en la pantalla y agregar esos datos repetidos a un archivo.

echo "hi there, Have to print this on screen and append to a file" 

Respondido 01 Feb 18, 16:02

La camiseta es perfecta para esto, pero esto también hará el trabajo.

ls -lr / > output | cat output

respondido 19 nov., 12:10

Eso es un error si la salida aún no existe y no hace lo que usted quiere si lo hace, en general no tiene sentido. Quizás quisiste decir ";" en lugar de "|" ? - roberto apuesta

Incluso si usaste un ;, la salida se retrasaría mucho durante un comando lento. - brad koch

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.