Mesclar stdout e stderr e criar cópias de cada um separadamente

Mesclar stdout e stderr e criar cópias de cada um separadamente

Meu objetivo é melhor explicado por exemplo. Para começar, aqui está uma função que produzirá um exemplo de saída, tanto em stdout quanto em stderr:

output() {
  printf '%s\n' 1 2
  printf '%s\n' errA errB 1>&2
  printf '%s\n' 3 4
}

Se você executar isso sozinho, ambos os fluxos serão impressos no terminal na ordem de execução:

$ output
1
2
errA
errB
3
4

Agora, esta função é simplesmente um espaço reservado para representar a saída (stdout e stderr) de algum script arbitrário que desejamos registrar. Especificamente, queremos criar três logs diferentes:

  1. A saída combinada da ordem de execução de stdout e stderr (ou seja, a saída acima).
  2. Apenas a saída stdout
  3. Apenas a saída stderr

A solução mais próxima que encontrei é esta:

$ { output > >(tee out) 2> >(tee err >&2); } > both 2>&1
$ ls
both  err  out
$ cat both
errA
errB
1
2
3
4
$ cat out
1
2
3
4
$ cat err
errA
errB

Como você pode ver, os arquivos oute errestão como desejado, mas o arquivo combinado bothnão mantém a ordem de execução.

Existe uma maneira de criar os 3 arquivos de log desejados simultaneamente?

Como pergunta bônus, a saída da ordem de execução é realmente garantida ao executar a outputfunção por conta própria? Tentei executar várias vezes, e o stdout e o stderr mistos no terminal são sempre os mesmos e na ordem correta. Mas isso não é a mesma coisa que uma garantia.

informação relacionada