¿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).
¿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).
Respuestas:
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.
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:
#basic principle (some un-necessary "{}" to visually help see the layers):
# { { complex command ;} | sed -e "s/^/TAGstdout/" ;} 2>&1 | read_stdin_and_redispatch
#exemple:
# complex command = a (slowed) ls of several things (some existing, others not)
# to see if the order of stdout&stderr is kept
#preparation, not needed for the "proof of concept", but needed for our specific exemple setup:
\rm out.file out_AND_err.file unknown unknown2
touch existing existing2 existing3
#and the (slow, too many execs, etc) "proof of concept":
uniquetag="_stdout_" # change this to something unique, that will NOT appear in all the commands outputs...
# avoid regexp characters ("+" "?" "*" etc) to make it easy to remove with another sed later on.
{
{ for f in existing unknown existing2 unknown2 existing3 ; do ls -l "$f" ; sleep 1; done ;
} | sed -u -e "s/^/${uniquetag}/" ;
} 2>&1 | while IFS="" read -r line ; do
case "$line" in
${uniquetag}*) printf "%s\n" "$line" | tee -a out_AND_err.file | sed -e "s/^${uniquetag}//" >> out.file ;;
*) printf "%s\n" "$line" >> out_AND_err.file ;;
esac;
done;
# see the results:
grep "^" out.file out_AND_err.file
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 en cat
lugar de grep "^"
? (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
cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err
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:
... | tee file1 file2
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:
... | tee -a file1 >>file2
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).
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
, entonces
(cmd | tee -a /dev/stderr) 2>> file1 >> file2
trabajará. La salida estándar de cmd
se envía tanto al stdout como al stderr de la tubería. El error estándar de la cmd
derivación tee
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.
out+err
yout
decir aquí. Nombres de archivo? ¿Flujos para ser redirigidos?