Що стосується рішення переадресувати багато команд одночасно:
#!/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 |
, принаймні трохи зручніше.