stderr (standard error) to standardowy strumień błędów w systemach uniksowych, oznaczony deskryptorem pliku numer 2. To osobny kanał, którym program wypluwa komunikaty diagnostyczne, ostrzeżenia i błędy — całkowicie niezależny od strumienia z normalnymi wynikami pracy. Dzięki temu możesz oddzielić to, co program faktycznie produkuje, od tego, co krzyczy, gdy coś idzie nie tak.
Jak to działa
Każdy proces w Linuksie i macOS dostaje na starcie trzy otwarte strumienie: stdin (deskryptor 0, wejście), stdout (deskryptor 1, normalne wyjście) i właśnie stderr (deskryptor 2). Konwencja jest prosta: wyniki, które chcesz dalej przetwarzać, lecą na stdout, a wszystko, co jest meta-informacją o przebiegu — błędy, postęp, ostrzeżenia — ląduje na stderr.
Dwa praktyczne powody tego podziału. Po pierwsze, stderr jest domyślnie niebuforowany (albo buforowany liniowo), więc komunikaty o błędach pojawiają się natychmiast, nawet jeśli program zaraz potem padnie. Po drugie, możesz przekierować każdy strumień osobno — i to jest cała magia.
Przykład z praktyki
Załóżmy, że robisz find / -name "*.conf" jako zwykły użytkownik. Posypią się dziesiątki linii Permission denied, które zaśmiecają wynik. Te komunikaty idą na stderr, więc możesz je wyciszyć, zachowując realne wyniki na stdout:
find / -name "*.conf" 2>/dev/null— wysyłastderrdo kosza../skrypt.sh >wynik.log 2>bledy.log— rozdziela wynik i błędy do osobnych plików../skrypt.sh >all.log 2>&1— scalastderrzestdoutw jeden plik (kolejność2>&1ma znaczenie!).
W skryptach Bash sam też wypychaj błędy na właściwy kanał: echo "Brak pliku konfiguracyjnego" >&2. Wtedy automat, który czyta twój skrypt, nie pomyli ostrzeżenia z danymi.
Częste pułapki
Najczęstszy zonk to zapis 2>&1 >plik w złej kolejności — wtedy stderr trafia tam, gdzie stdout wskazywał przed przekierowaniem, czyli na terminal, a nie do pliku. Pamiętaj: powłoka czyta przekierowania od lewej do prawej. Drugi mit: że stderr to zawsze błędy krytyczne. Nieprawda — mnóstwo narzędzi (np. curl, wget, ffmpeg) wrzuca tam pasek postępu i logi, które są zupełnie normalne. O tym, czy coś się udało, świadczy kod wyjścia (exit code), a nie sama obecność tekstu na stderr.
Pojęcia powiązane: stdout, stdin, deskryptor pliku, przekierowanie (redirection), potok (pipe), /dev/null, exit code, tee.