¿Cómo redirigir stderr y stdout a diferentes archivos y también mostrarlos en la terminal?

30

Quiero ver la salida de un comando en el terminal como si no hubiera redirección. Además, stderr debe redirigirse a err.log y stdout debe redirigirse a stdout.log.

Sería bueno tener también la copia exacta de lo que se muestra en la terminal, es decir, errores impresos como y cuando ocurre, en un archivo separado: stdouterr.log.

balki
fuente
@Nuno No, no lo es. El OP quiere tener diferentes archivos para stdout y stderr.
dogbane
@ Dogbane Sí, tienes razón. Lo siento por eso.
Nuno C. Inácio
Todavía encuentro esta pregunta muy familiar. Permítanme buscar ... Aquí hay una muy similar unix.stackexchange.com/q/4195/250 , y aquí hay una relacionada unix.stackexchange.com/q/1416/250
phunehehe

Respuestas:

37

Use el teecomando de la siguiente manera:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 es cómo intercambiar stderr y stdout, porque tee solo puede aceptar stdout.

Eche un vistazo al comando tee de Unix para obtener redirecciones más avanzadas tee.

dogbane
fuente
Buena solución ¿Hay alguna forma de obtener el código de salida cmd?
turbanoff
2
@turbanoff Reemplazar cmdcon (cmd ; echo >exit_code.txt $?).
Parthian Shot
Creo que esto debería preservar mejor el orden de salida de las cosas a la línea de comando:((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log)
TTT
5

Creo que registrar stdout y stderr en dos archivos diferentes es una idea espléndida. ¿No hace que los registros sean asíncronos? Así que probé lo siguiente:

  • stdout a "stdout.log" (como sugirió dogbane)
  • stderror a "stderr.log" (como sugirió dogbane)
  • toda la salida a "all.log" y
  • todavía puedo ver la salida en la pantalla (¡aunque en un terminal separado!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

en otra terminal

tail -f --sleep-interval=2 all.log
Sreeni
fuente
¿No es posible dirigir stderr directamente a un segundo tty? Entonces no se requiere un archivo de registro.
Steven Lu
@StevenLu sí, si conoce el nombre y tiene permiso para escribir en el segundo tty que se puede hacer.
Jasen
1
más fácil sería &| tee all.logal final del comando en lugar de&> all.log
Jasen
@Jasen: segunda vez que veo &|. También entiendo &>, |&pero ¿qué &|significa en este contexto? No pude encontrar una referencia de sintaxis adecuada, ni en la red, ni siquiera consultando la página del manual de bash "bash (1)" ... Tx
Cbhihe
1
@Cbhihe, por lo que puedo decir, no hace nada, quise decir|&
Jasen,
3

@ Dogbane, gracias.
También encontré otra forma que guarda las dos secuencias aproximadamente en el orden, ya que se imprimirían sin redireccionamiento.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

Pero esto solo funciona con los shells que admiten la sustitución de procesos.

balki
fuente
-2

prueba esto :

command 2>&1 | tee bothLog
vasil
fuente
44
Hola vasile, esto no responde la pregunta: balki necesita archivos separados para stdout y stderr, su solución mezclaría ambos en la misma secuencia.
Mat
¿Por qué las personas fusionan stdout y stderr juntas? ¿O decirle a otros que lo hagan?
nurettin