Eu sou novo no bash e por toda a minha vida não consigo descobrir como executar um determinado comando, supor ./fff
e 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
cat
realmente substituir "a" por "alguns"?Respostas:
Você precisará segurar a saída stderr em algum lugar de qualquer maneira para poder exibi-la no final.
Um arquivo vem à mente:
Ou memória (aqui usando
sponge
demoreutils
):{...} 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 stdoutfff
).fff <redirs> | sponge <redirs>
,fff
esponge
começou simultaneamente (com<redirs>
aplicação independente), comfff
o stdout indo para um pipe esponge
o stdin sendo a outra extremidade do pipe.2>&1
: fd 2 defff
(stderr) aponta para a mesma coisa que em 1: o pipe neste momento, entãofff
o erro ocorresponge
através desse tubo.>&3
: agora stdout aponta para o stdout original (redirecione de volta para o que era)3>&-
: fechamos o fd 2 quefff
não precisasponge
acumula sua entrada e a exibe apenas (em seu stdout que foi redirecionado>&2
para o mesmo recurso que stderr) após detectar eof em seu stdin (supostamente quandofff
termina e já gravou toda sua saída em seu stdout).Se
sponge
não estiver instalado, você poderá substituí-lo porperl -0777 -pe ''
. Com-pe ''
,perl
lê 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.fonte
tee
vez desponge
...?tee
não contém dados, grava-os assim que os lê.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 fazercat ferr.txt >&2
para gravar as informações stderr para o stderr.