¿Cómo puedo lograr
cmd >> file1 2>&1 1>>file2
Es decir, stdout y stderr deberían redirigir a un archivo (archivo1) y solo stdout (archivo2) debería redirigir a otro (ambos en modo de agregado).
El problema es que cuando redirige su salida, ya no está disponible para la próxima redirección. Puede canalizar tee
en una subshell para mantener la salida para la segunda redirección:
( cmd | tee -a file2 ) >> file1 2>&1
o si desea ver la salida en la terminal:
( cmd | tee -a file2 ) 2>&1 | tee -a file1
Para evitar agregar el stderr del primero tee
a file1
, debe redirigir el stderr de su comando a algún descriptor de archivo (por ejemplo, 3), y luego agregar esto a stdout nuevamente:
( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
(gracias @ fra-san)
Con zsh
:
cmd >& out+err.log > out.log
En modo agregar:
cmd >>& out+err.log >> out.log
En zsh
, y siempre que la mult_ios
opción no se haya deshabilitado, cuando un descriptor de archivo (aquí 1) se redirige varias veces para escribir, el shell implementa una función integrada tee
para duplicar la salida a todos los destinos.
out+err
yout
decir aquí. Nombres de archivo? ¿Flujos para ser redirigidos?cmd >& file1 > file2
Podrías: etiquetar stdout (usando un sed UNBUFFERED, es decir:)
sed -u ...
, hacer que stderr también vaya a stdout (sin etiquetar, ya que no pasó por ese etiquetado sed), y así poder diferenciar los 2 en el archivo de registro resultante.Lo siguiente: es lento (puede optimizarse seriamente, usando por ejemplo un script perl en lugar de while ...; do ...; hecho, por ejemplo, ¡eso generará subshells y comandos en cada línea!), Extraño (parece que necesito las 2 {} etapas para cambiar el nombre de una stdout y luego en la otra agregar el stderr "fallado"), etc. Pero es: una " prueba de concepto " que intentará mantener la salida ordena lo más posible stdout & stderr tanto como sea posible:
fuente
ls unknown
) para imprimir algo en stderr?>&2 echo "error"
estaría bien. (2)tee
puede agregar a múltiples archivos a la vez. (3) ¿Por qué no solo encat
lugar degrep "^"
? (4) su script fallará cuando comience la salida stderr_stdout_
. (5) ¿Por qué?ls loop
saldrá en stdout y stderr, mezclado (alternativamente), en un orden controlado, para que podamos verificar que mantuvimos ese orden stderr / stdout a pesar del etiquetado de stdout 2): cola de gnu, tal vez, pero no cola regular (ex, en aix.). 3): grep "^" también muestra ambos nombres de archivo. 4): esto puede ser cambiado por la variable. 5): el ejemplo complicado funciona en viejos oses (ej., Viejo aix) donde lo probé (no hay perl disponible).uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406
...)Si el orden de salida debe ser: stdout, entonces stderr ; no hay solución solo con redireccionamiento.
El stderr debe almacenarse en un archivo temporal
Descripción:
La única forma de redirigir una salida (una fd como stdout o stderr) a dos archivos es reproducirla. El comando
tee
es la herramienta correcta para reproducir el contenido de un descriptor de archivo. Entonces, una idea inicial para tener una salida en dos archivos sería usar:Eso reproduce el stdin de tee en ambos archivos (1 y 2) dejando la salida de tee aún sin usar. Pero necesitamos agregar (usar
-a
) y solo necesitamos una copia. Esto resuelve ambos problemas:Para suministrar
tee
stdout (el que hay que repetir) necesitamos consumir stderr directamente fuera del comando. Una forma, si el orden no es importante (el orden de salida se conservará (muy probablemente) como generado, el que se envíe primero se almacenará primero). Ya sea:cmd 2>>file1 | tee -a file2 >>file1
cmd 2>>file1 > >( tee -a file2 >>file1 )
( cmd | tee -a file2 ) >> file1 2>&1
La opción 2 solo funciona en algunos depósitos. La opción 3 usa una subshell adicional (más lenta) pero usa los nombres de archivo solo una vez.
Pero si stdout debe ser el primero (cualquiera que sea la salida del pedido que se genere), debemos almacenar stderr para agregarlo al archivo al final (primera solución publicada).
fuente
sponge
hace:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
En interés de la diversidad:
Si su sistema es compatible
/dev/stderr
, entoncestrabajará. La salida estándar de
cmd
se envía tanto al stdout como al stderr de la tubería. El error estándar de lacmd
derivacióntee
y sale del stderr de la tubería.Asi que
cmd
, ycmd
, entremezclado.Entonces se trata simplemente de enviar esas transmisiones a los archivos correctos.
Como ocurre con casi cualquier enfoque como este (incluida la respuesta de Stéphane ), es
file1
posible que las líneas se salgan de orden.fuente