Що стосується рішення переадресувати багато команд одночасно:
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee -a $DEBUGLOG
Чому ваше оригінальне рішення не працює: exec 2> & 1 перенаправить стандартний вихід помилки на стандартний вихід вашої оболонки, який, якщо ви запустите сценарій з консолі, буде вашою консоллю. перенаправлення труби на команди буде перенаправляти тільки стандартний вихід команди.
З точки зору somecommand, його стандартний вихід надходить у з'єднану з ним трубу, teeа стандартна помилка переходить у той самий файл / псевдофайл, що і стандартна помилка оболонки, яку ви перенаправляєте на стандартний вихід оболонки, який буде консоль, якщо ви запускаєте програму з консолі.
Єдиний вірний спосіб пояснити це - побачити, що насправді відбувається:
Первісне середовище вашої оболонки може виглядати приблизно так, якщо ви запускаєте її з терміналу:
stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42
Після того як ви перенаправляєте стандартну помилку на стандартний вихід ( exec 2>&1), ви ... в основному нічого не змінюєте. Але якщо ви будете перенаправляти стандартний вихід сценарію до файлу, ви отримаєте таке середовище:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42
Тоді перенаправлення стандартної помилки оболонки на стандартний вихід закінчиться так:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file
Виконання команди успадкує це середовище. Якщо ви запускаєте команду і передаєте її в трійник, середовищем команди буде:
stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file
Отже стандартна помилка вашої команди все ще переходить у те, що оболонка використовує як свою стандартну помилку.
Насправді ви можете побачити середовище команди, заглянувши в /proc/[pid]/fd: використовуйте ls -lтакож для переліку вмісту символічного посилання. 0Файл тут стандартне введення, 1стандартний вихід і 2стандартна помилка. Якщо команда відкриє більше файлів (і це робить більшість програм), ви також побачите їх. Програма може також вибрати для перенаправлення або закриття стандартного введення / виведення і повторного використання 0, 1і 2.
|&працює як ярлик2>&1 |, принаймні трохи зручніше.