exibe STDOUTs antes de STDERR?

9

Eu sou novo no bash e por toda a minha vida não consigo descobrir como executar um determinado comando, supor ./fffe imprimir stdouts regulares antes do stderr (estou confuso sobre o significado)

por exemplo

$ 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

precisa 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

Entendo que preciso redirecionar minha saída primeiro para um arquivo e depois anexar o erro ao mesmo arquivo, no entanto, essa é a saída que recebo para

$ 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
Miau
fonte
2
Será que catrealmente substituir "a" por "alguns"?
Dmitry Grigoryev
oh dang, eu poderia ter estragado a corda. Vou editá-lo imediatamente @DmitryGrigoryev
MeOw 15/01

Respostas:

18

Você precisará segurar a saída stderr em algum lugar de qualquer maneira para poder exibi-la no final.

Um arquivo vem à mente:

fff 2> file; cat file >&2

Ou memória (aqui usando spongede moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: dentro {...}do descritor de arquivo (fd) 3 pontos para o mesmo recurso que o stdout original (para que possamos usá-lo para restaurar o stdout fff).
  • fff <redirs> | sponge <redirs>, fffe spongecomeçou simultaneamente (com <redirs>aplicação independente), com fffo stdout indo para um pipe e spongeo stdin sendo a outra extremidade do pipe.
  • 2>&1: fd 2 de fff(stderr) aponta para a mesma coisa que em 1: o pipe neste momento, então fffo erro ocorre spongeatravés desse tubo.
  • >&3: agora stdout aponta para o stdout original (redirecione de volta para o que era)
  • 3>&-: fechamos o fd 2 que fffnão precisa
  • spongeacumula sua entrada e a exibe apenas (em seu stdout que foi redirecionado >&2para o mesmo recurso que stderr) após detectar eof em seu stdin (supostamente quando ffftermina e já gravou toda sua saída em seu stdout).

Se spongenão estiver instalado, você poderá substituí-lo por perl -0777 -pe ''. Com -pe '', perllê um registro em um momento de sua entrada e escreve-lo em stdout. -0777é o modo slurp em que o registro (apenas um nesse caso) é a entrada inteira.

Stéphane Chazelas
fonte
Por favor, divida-o se tiver tempo!
George Udosen
Podemos usar em teevez de sponge...?
George Vasiliou
@GeorgeUdosen see edit.
Stéphane Chazelas
1
@GeorgeVasiliou, teenão contém dados, grava-os assim que os lê.
Stéphane Chazelas
2
@MeOw: Tudo bem, mas, como mostra a terceira linha da resposta de Stéphane, você não precisa salvar o stdout; apenas faça cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt. (E você provavelmente não quer usar >>.) Além disso, Stéphane faz o excelente momento que você provavelmente deve fazer cat ferr.txt >&2para gravar as informações stderr para o stderr.
G-Man diz 'Reinstate Monica'