Cómo redirigir la salida a un archivo y stdout

En bash, llamar a foo mostraría cualquier salida de ese comando en el stdout.

Llamar a foo > output redirigiría cualquier salida de ese comando al archivo especificado (en este caso ‘salida’).

¿Hay alguna manera de redirigir la salida a un archivo y hacer que se visualice en stdout?

El comando que desea se llama tee :

 foo | tee output.file 

Por ejemplo, si solo se preocupa por 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 (salida estándar / salida estándar), de modo que ambos se escriben como stdout. También se dirige al archivo de salida dado a partir del comando tee .

Además, si desea agregar al archivo de registro, use tee -a como:

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

2>&1 vuelca las streams stderr y stdout. tee outfile archivo de tee outfile toma la secuencia que recibe y la escribe en la pantalla y en el archivo “archivo de salida”.

Esto es probablemente lo que la mayoría de la gente está buscando. La situación probable es que algún progtwig o script esté trabajando duro durante mucho tiempo y generando muchos resultados. El usuario desea verificarlo periódicamente para ver el progreso, pero también desea que el resultado se escriba en un archivo.

El problema (especialmente cuando se mezclan las streams stdout y stderr) es que hay confianza en las streams que el progtwig descarga. Si, por ejemplo, todas las escrituras en stdout no se vacían, pero todas las escrituras en stderr se vacían, entonces terminarán fuera del orden cronológico en el archivo de salida y en la pantalla.

También es malo si el progtwig solo emite 1 o 2 líneas cada pocos minutos para informar el progreso. En tal caso, si el progtwig no borraba 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 unbuffer progtwig, que forma parte del paquete de expect , resolverá el problema del almacenamiento en búfer. Esto hará que stdout y stderr escriban en la pantalla y el archivo inmediatamente y los mantenga sincronizados cuando se combinan y se redirigen a tee . P.ej:

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

Otra forma que funciona para mí es

  |& tee  

como se muestra en el manual de gnu bash

Ejemplo:

 ls |& tee files.txt 

Si se usa ‘| &’, el error estándar de command1 , además de su salida estándar , se conecta a la entrada estándar de command2 a través de la tubería; es una abreviatura de 2> y 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 la redirección

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

 ls -lR / | tee -a output.file 

Algo para agregar …

El paquete descargable tiene problemas de compatibilidad con algunos paquetes en versiones de fedora y redhat Unix.

Dejando de lado los problemas

Lo siguiente funcionó para mí

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

Gracias ScDF y matthew tus entradas me ahorraron mucho tiempo …

usar la tail -f output debería funcionar.

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

En el caso donde necesite hacer esto como otro usuario

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

Tenga en cuenta que el eco ocurrirá cuando usted y el archivo escriban como “un_usuario” lo que NO funcionará si ejecutara el eco como “algún_usuario” y redirigiera el resultado con >> “archivo_alguno” porque la redirección de archivos ocurrirá como tu.

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

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

< command > | tee >> filename < 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 anexar los datos repetidos a un archivo

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

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

 ls -lr / > output | cat output