GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo escribo stderr en un archivo mientras uso tee con una tubería?

Supongo que aún desea ver STDERR y STDOUT en la terminal. Podrías elegir la respuesta de Josh Kelley, pero creo que mantener un tail alrededor en segundo plano, lo que genera su archivo de registro muy pirateado y torpe. Observe cómo necesita mantener un exra FD y luego limpiarlo eliminándolo y técnicamente debería hacerlo en un trap '...' EXIT .

Hay una mejor manera de hacer esto, y ya la has descubierto:tee .

Solo que, en lugar de usarlo solo para su salida estándar, tenga una camiseta para la salida estándar y otra para la salida estándar. ¿Cómo lograrás esto? Sustitución de procesos y redirección de archivos:

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

Dividámoslo y expliquemos:

> >(..)

>(...) (sustitución de proceso) crea un FIFO y permite tee Escúchalo. Luego, usa > (redireccionamiento de archivos) para redirigir el STDOUT de command al FIFO que tu primer tee está escuchando.

Lo mismo para el segundo:

2> >(tee -a stderr.log >&2)

Usamos la sustitución de procesos nuevamente para hacer un tee proceso que lee de STDIN y lo vuelca en stderr.log . tee genera su entrada en STDOUT, pero como su entrada es nuestro STDERR, queremos redirigir tee 's STDOUT a nuestro STDERR de nuevo. Luego usamos la redirección de archivos para redirigir command 's STDERR a la entrada de FIFO (tee 's STDIN).

Consulte http://mywiki.wooledge.org/BashGuide/InputAndOutput

La sustitución de procesos es una de esas cosas realmente encantadoras que obtienes como bonificación al elegir bash como tu caparazón en lugar de sh (POSIX o Bourne).

En sh , tendrías que hacer las cosas manualmente:

out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"

por qué no simplemente:

./aaa.sh 2>&1 | tee -a log

Esto simplemente redirige stderr a stdout , por lo que tee hace eco tanto en el registro como en la pantalla. Tal vez me estoy perdiendo algo, porque algunas de las otras soluciones parecen realmente complicadas.

Nota: Desde la versión 4 de bash, puede usar |& como abreviatura de 2>&1 | :

./aaa.sh |& tee -a log

Esto puede ser útil para las personas que lo encuentran a través de Google. Simplemente descomente el ejemplo que desea probar. Por supuesto, no dude en cambiar el nombre de los archivos de salida.

#!/bin/bash

STATUSFILE=x.out
LOGFILE=x.log

### All output to screen
### Do nothing, this is the default


### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1


### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1


### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)


### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)


### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}


### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)


### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}


### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)


echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}

Linux
  1. ¿Cómo escribir un archivo con C en Linux?

  2. ¿Cómo canalizo una llamada de subproceso a un archivo de texto?

  3. ¿Cómo agregar a un archivo como sudo?

  4. ¿Cómo rellenar un archivo con FF usando dd?

  5. Cómo encontrar un archivo con nombre =php.ini en Linux usando el comando grep

Cómo escribir un script Bash con ejemplos

Cómo redirigir stderr a stdout en Bash

Cómo:una introducción al uso de Git

Tutorial de Unix Sed:Cómo escribir en un archivo usando Sed

¿Cómo agregar a un archivo en C, usando Abrir en modo O_APPEND en Linux?

¿Cómo cambiar un archivo en el lugar usando awk? (como con sed -i)