Объединить stdout и stderr и создать копии каждого по отдельности

Объединить stdout и stderr и создать копии каждого по отдельности

Моя цель лучше всего объясняется на примере. Для начала вот функция, которая выведет пример вывода как на stdout, так и на stderr:

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

Если запустить это отдельно, оба потока будут выведены на терминал в порядке выполнения:

$ output
1
2
errA
errB
3
4

Теперь эта функция — просто заглушка для представления вывода (stdout и stderr) некоторого произвольного скрипта, который мы хотим зарегистрировать. В частности, мы хотим создать три разных журнала:

  1. Объединенный вывод stdout и stderr в порядке выполнения (т. е. вывод выше).
  2. Только вывод stdout
  3. Только вывод stderr

Самое близкое решение, которое я придумал, это:

$ { 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

Как видите, файлы outи errсоответствуют желаемому, но объединенный файл bothне сохраняет порядок выполнения.

Есть ли способ создать 3 нужных файла журнала одновременно?

Бонусный вопрос: гарантируется ли порядок выполнения вывода при запуске функции outputотдельно? Я пробовал запускать много раз, и смешанный stdout и stderr в терминале всегда одинаковы и в правильном порядке. Но это не то же самое, что гарантия.

Связанный контент