Soy nuevo en bash y no puedo por mi vida descubrir cómo ejecutar un determinado comando, supongamos ./fff
e 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
cat
Realmente reemplazó "a" por "algunos"?Respuestas:
Deberá mantener la salida stderr en algún lugar de todos modos para poder mostrarla al final.
Me viene a la mente un archivo :
O memoria (aquí usando
sponge
desdemoreutils
):{...} 3>&1
: dentro{...}
del descriptor de archivo (fd) 3 puntos al mismo recurso que el stdout original (para que podamos usarlo para restaurar stdoutfff
).fff <redirs> | sponge <redirs>
,fff
ysponge
comenzó simultáneamente (con<redirs>
aplicado independientemente) con la salida estándar quefff
va a una tubería, ysponge
la entrada estándar es el otro extremo de la tubería.2>&1
: fd 2 defff
(stderr) apunta a lo mismo que en 1: la tubería en este punto, por lo quefff
el error pasasponge
por esa tubería.>&3
: ahora stdout apunta al stdout original (redirige de nuevo a lo que era)3>&-
: cerramos fd 2 quefff
no necesitasponge
acumula su entrada y solo la muestra (en su stdout que se ha redirigido>&2
al mismo recurso que stderr) después de detectar eof en su stdin (se supone que es cuandofff
termina y ya ha escrito toda su salida en su stdout).Si
sponge
no está instalado, puede reemplazarlo porperl -0777 -pe ''
. Con-pe ''
,perl
lee un registro a la vez desde su entrada y lo escribe en stdout.-0777
es el modo slurp donde el registro (solo uno en ese caso) es la entrada completa.fuente
tee
lugar desponge
...?tee
no contiene datos, los escribe tan pronto como los lee.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 hacercat ferr.txt >&2
para escribir la información de stderr en el stderr.