Jeśli chodzi o rozwiązanie przekierowywania wielu poleceń jednocześnie:
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee -a $DEBUGLOG
Dlaczego oryginalne rozwiązanie nie działa: exec 2> i 1 przekieruje standardowe wyjście błędu na standardowe wyjście powłoki, która, jeśli uruchomisz skrypt z konsoli, będzie twoją konsolą. przekierowanie potoku dla poleceń przekieruje jedynie standardowe wyjście polecenia.
Z punktu widzenia somecommand
standardowego wyjścia przechodzi do podłączonego potoku, tee
a standardowy błąd trafia do tego samego pliku / pseudopliku, co standardowy błąd powłoki, który przekierowuje się do standardowego wyjścia powłoki, którym będzie konsoli, jeśli uruchamiasz program z konsoli.
Jedynym prawdziwym sposobem na wyjaśnienie tego jest zobaczenie, co się naprawdę dzieje:
Oryginalne środowisko twojej powłoki może wyglądać tak, jeśli uruchomisz ją z terminala:
stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42
Po przekierowaniu standardowego błędu do standardowego wyjścia ( exec 2>&1
), ... zasadniczo nic nie zmieniasz. Ale jeśli przekierujesz standardowe wyjście skryptu do pliku, uzyskasz takie środowisko:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42
Następnie przekierowanie standardowego błędu powłoki na standardowe wyjście skończyłoby się tak:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file
Uruchomienie polecenia odziedziczy to środowisko. Jeśli uruchomisz polecenie i potokujesz je do tee, środowisko polecenia to:
stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file
Zatem standardowy błąd polecenia nadal dotyczy tego, co powłoka używa jako standardowego błędu.
Środowisko polecenia można zobaczyć, patrząc /proc/[pid]/fd
: użyj, ls -l
aby wyświetlić także zawartość dowiązania symbolicznego. 0
Plik tutaj jest standardowe wejście, 1
to standardowe wyjście i 2
jest błąd standardowy. Jeśli polecenie otworzy więcej plików (a większość programów tak robi), zobaczysz je również. Program może również wybrać przekierowanie lub zamknięcie swojego standardowego wejścia / wyjścia i ponowne użycie 0
, 1
oraz 2
.
|&
działa jako skrót2>&1 |
, jest co najmniej nieco wygodniejszy.