mostrar STDOUT antes de STDERR?


9

Soy nuevo en bash y no puedo por mi vida descubrir cómo ejecutar un determinado comando, supongamos ./fffe imprimo stdouts regulares antes de stderr (estoy confundido sobre el significado)

por ejemplo

$ printf "I am a\ndrill\n" > fff; 
$ cat fff nofile fff nofile fff

I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill

necesita imprimir como:

I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory

Entiendo que necesito redirigir mi salida primero a un archivo y luego agregar el error al mismo archivo, sin embargo, esta es la salida que obtengo

$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see 

I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory

2
¿ catRealmente reemplazó "a" por "algunos"?
— Dmitry Grigoryev

oh dang, podría haber estropeado la cuerda. Lo editaré de inmediato @DmitryGrigoryev
— MeOw

Respuestas:


18

Deberá mantener la salida stderr en algún lugar de todos modos para poder mostrarla al final.

Me viene a la mente un archivo :

fff 2> file; cat file >&2

O memoria (aquí usando spongedesde moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: dentro {...}del descriptor de archivo (fd) 3 puntos al mismo recurso que el stdout original (para que podamos usarlo para restaurar stdout fff).
  • fff <redirs> | sponge <redirs>, fffy spongecomenzó simultáneamente (con <redirs>aplicado independientemente) con la salida estándar que fffva a una tubería, y spongela entrada estándar es el otro extremo de la tubería.
  • 2>&1: fd 2 de fff(stderr) apunta a lo mismo que en 1: la tubería en este punto, por lo que fffel error pasa spongepor esa tubería.
  • >&3: ahora stdout apunta al stdout original (redirige de nuevo a lo que era)
  • 3>&-: cerramos fd 2 que fffno necesita
  • spongeacumula su entrada y solo la muestra (en su stdout que se ha redirigido >&2al mismo recurso que stderr) después de detectar eof en su stdin (se supone que es cuando ffftermina y ya ha escrito toda su salida en su stdout).

Si spongeno está instalado, puede reemplazarlo por perl -0777 -pe ''. Con -pe '', perllee un registro a la vez desde su entrada y lo escribe en stdout. -0777es el modo slurp donde el registro (solo uno en ese caso) es la entrada completa.


Por favor, divídalo si tiene tiempo!
— George Udosen

¿Podemos usar en teelugar de sponge...?
— George Vasiliou

@GeorgeUdosen ver editar.
— Stéphane Chazelas

1
@GeorgeVasiliou, teeno contiene datos, los escribe tan pronto como los lee.
— Stéphane Chazelas

2
@MeOw: Eso está bien, pero, como muestra la tercera línea de la respuesta de Stéphane, no es necesario guardar el stdout; solo hazlo cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt. (Y probablemente no quiera usarlo >>). Además, Stéphane hace el excelente punto que probablemente debería hacer cat ferr.txt >&2para escribir la información de stderr en el stderr.
— G-Man dice 'Reincorporar a Monica' el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.