Redirection (przekierowanie) to mechanizm powłoki (np. bash, zsh), który pozwala Ci sterować tym, skąd program pobiera dane i dokąd je wysyła — bez modyfikowania samego programu. Zamiast wpisywać dane z klawiatury i oglądać wynik na ekranie, podłączasz wejście i wyjście procesu do plików albo innych strumieni. Najprostszy przykład: echo "cześć" > plik.txt zapisuje tekst do pliku zamiast wypisywać go w terminalu.
Jak to działa
Każdy proces w Linuksie startuje z trzema otwartymi deskryptorami plików (file descriptors): 0 to standardowe wejście (stdin), 1 to standardowe wyjście (stdout), a 2 to wyjście błędów (stderr). Redirection po prostu mówi powłoce: „podmień to, gdzie wskazuje dany deskryptor”. Operator > przekierowuje stdout do pliku (nadpisując go), >> dopisuje na koniec, a < bierze zawartość pliku jako stdin.
Strumienie możesz też łączyć ze sobą. Zapis 2>&1 oznacza „wyślij stderr tam, gdzie aktualnie idzie stdout". Dzięki temu zarówno normalne komunikaty, jak i błędy trafiają w jedno miejsce — przydatne, gdy logujesz działanie skryptu do pliku.
Przykład z praktyki
Załóżmy, że uruchamiasz backup.sh w nocy z crona i chcesz mieć pełny log:
./backup.sh > backup.log 2>&1— i stdout, i stderr lądują wbackup.log.grep "error" log.txt > bledy.txt— wynik wyszukiwania zapisujesz do osobnego pliku.command 2> /dev/null— kierujesz błędy do „czarnej dziury", czyli je wyrzucasz.
/dev/null to specjalny plik, który pochłania wszystko, co do niego trafi — idealny, gdy jakiś komunikat Ci po prostu przeszkadza.
Częste błędy
Po pierwsze, kolejność ma znaczenie. > plik 2>&1 działa inaczej niż 2>&1 > plik — w tym drugim stderr zostaje przypięty do ekranu, zanim stdout pójdzie do pliku. Po drugie, > bezlitośnie nadpisuje plik bez ostrzeżenia, więc jeśli pomylisz go z >>, tracisz dotychczasową zawartość. Po trzecie, nie myl redirection z | (pipe): pipe łączy wyjście jednego programu z wejściem drugiego, a redirection rozmawia z plikami.
Pojęcia powiązane
Warto znać też: pipe (|), file descriptors, stdin/stdout/stderr, tee (zapis do pliku i na ekran jednocześnie), here-document (<<) oraz /dev/null.