Как перенаправить stderr и stdout в разные файлы, а также отобразить в терминале?


30

Я хочу видеть вывод команды в терминале, как если бы не было перенаправления. Кроме того, stderr необходимо перенаправить на err.log, а stdout - на stdout.log.

Было бы также неплохо иметь точную копию того, что отображается в терминале, т.е. ошибки, напечатанные как и когда это происходит, в отдельном файле: stdouterr.log.


@ Нуно Нет, это не так. ОП хочет иметь разные файлы для stdout и stderr.
Dogbane

@ Dogbane Да, ты прав. Прости за это.
Нуно К. Инасиу

Я до сих пор нахожу этот вопрос очень знакомым. Позвольте мне посмотреть ... Вот очень похожий unix.stackexchange.com/q/4195/250 , а вот связанный unix.stackexchange.com/q/1416/250
phunehehe

Ответы:


37

Используйте teeкоманду следующим образом:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 это то, как вы меняете stderr и stdout, потому что tee может принимать только stdout.

Взгляните на команду Unix tee для более продвинутого использования перенаправлений tee.


Хорошее решение. Есть ли способ получить код выхода cmd?
turbanoff

2
@turbanoff Заменить cmdна (cmd ; echo >exit_code.txt $?).
Парфянский выстрел

Я считаю, что это должно лучше сохранить порядок вещей, выводимых в командную строку:((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log)
TTT

5

Я думаю, что запись stdout и stderr в два разных файла - отличная идея. Разве это не делает журналы асинхронными? Поэтому я опробовал следующее:

  • стандартный вывод "stdout.log" (как и предполагал догбейн)
  • stderror к "stderr.log" (как предположил догбейн)
  • все вывести на «all.log» и
  • все еще будет в состоянии видеть вывод на дисплее (хотя в отдельном терминале!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

в другом терминале

tail -f --sleep-interval=2 all.log

Разве нельзя напрямую направить stderr ко второму tty? Тогда никакой лог-файл не требуется.
Стивен Лу

@ StevenLu Да, если вы знаете имя и имеете разрешение на запись во второй tty, это можно сделать.
Jasen

1
проще было бы &| tee all.logна конце команды вместо&> all.log
Jasen

@Jasen: второй раз вижу &|. Я тоже понимаю &>, |&но что &|значит в этом контексте? Я не смог найти подходящую ссылку на синтаксис, не в сети, даже не обращаясь к странице руководства bash "bash (1)" ... Tx
Cbhihe

1
@ Cbhihe, насколько я могу судить, ничего не делает, я хотел сказать|&
Jasen

3

@ Dogbane, спасибо.
Я также нашел другой способ, который сохраняет оба потока примерно в том порядке, в котором они будут напечатаны без перенаправления.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

Но это работает только с оболочками, которые поддерживают процесс замены.


-2

попробуй это :

command 2>&1 | tee bothLog

4
Здравствуйте vasile, это не отвечает на вопрос: balki нужны отдельные файлы для stdout и stderr, ваше решение будет смешивать оба в одном потоке.
Мат

Почему люди объединяют stdout и stderr вместе? Или сказать другим, чтобы сделать это?
nurettin
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.