Як перенаправити stderr та stdout в різні файли, а також відобразити в терміналі?


30

Я хочу бачити вихід команди в терміналі так, ніби перенаправлення не було. Також stderr потрібно переспрямувати на err.log, а stdout потрібно переспрямувати на stdout.log.

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


@Nuno Ні, це не так. ОП хоче мати різні файли для stdout та stderr.
собачка

@dogbane Так, ти маєш рацію. Вибач за це.
Nuno C. Inácio

Я все ще вважаю це питання дуже знайомим. Дозвольте мені подивитися ... Ось дуже схожий на 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, тому що трійник може приймати лише stdout.

Погляньте на команду Unix tee для більш вдосконалених переспрямувань за допомогою tee.


приємне рішення. Чи є спосіб отримати код виходу cmd?
турбоноф

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 до "stdout.log" (як запропонував dogbane)
  • 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, що можна зробити.
Ясен

1
легше було б &| tee all.logв кінці команди замість&> all.log
Jasen

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

1
@Cbhihe, наскільки я можу сказати, це нічого не робить, я мав намір сказати|&
Ясен

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 разом? Або скажіть іншим зробити це?
Нуреттін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.