Przejdź do treści
Lekcja 6 z 117

Kurs › Moduł 1 › Lekcja 6

Gdzie idzie wynik komendy

⏱ ok. 4 min czytania· moduł 1: Praca w powłoce

Po tej lekcji: kursant zapisuje wynik komend do plików, dopisuje, oddziela błędy od normalnych wyników i wie, co to /dev/null.

Wstęp

Każda komenda, którą do tej pory wpisałeś, wypisywała wynik na ekran. Przeczytałeś, zamknąłeś terminal i wynik przepadł.

A co, jeśli chcesz go zachować? Listę plików do raportu. Log z nocnej kopii zapasowej. Błędy, żeby rano zobaczyć, co poszło nie tak.

Dziś nauczysz się kierować to, co komendy mówią, tam, gdzie chcesz.

Dwa głośniki

Każda komenda ma dwa głośniki.

Pierwszym mówi normalne rzeczy: listę plików, wynik, odpowiedź. Fachowo: standardowe wyjście, w skrócie stdout.

Drugim krzyczy, kiedy coś poszło nie tak: „nie ma takiego pliku”, „brak uprawnień”. Fachowo: standardowe wyjście błędów, w skrócie stderr.

Na ekranie oba brzmią tak samo, bo oba są podłączone do terminala. Ale Bash pozwala je rozdzielić. I podłączyć każdy w inne miejsce.

Wracając do urzędu: urzędnik normalną odpowiedź podaje Ci do ręki, a skargi wkłada do osobnej teczki. Ty decydujesz, która teczka idzie do segregatora, a która do kosza.

Zapis do pliku: >

ls > lista.txt

Zamiast na ekran, wynik ls ląduje w pliku lista.txt. Na ekranie nic się nie pojawi. Sprawdź cat lista.txt.

To jest właśnie prawdziwe pisanie do plików, które obiecałem dwa lekcje temu:

echo "Kupić mleko" > zakupy.txt

Uwaga: > nadpisuje

echo "Kupić chleb" > zakupy.txt
cat zakupy.txt

Mleka już nie ma. Pojedyncza strzałka kasuje to, co było w pliku, i wpisuje nowe. Bez pytania. Jak rm, tylko bardziej podstępne, bo nie wygląda na kasowanie.

Dopisywanie: >>

echo "Kupić mleko" >> zakupy.txt
echo "Kupić jajka" >> zakupy.txt
cat zakupy.txt

Podwójna strzałka dopisuje na końcu. Tak działają logi: każde zdarzenie to nowa linijka na końcu pliku.

Podpowiedź na pamięć: jedna strzałka to jedna kartka, wyrzucasz starą i piszesz nową. Dwie strzałki to zeszyt, dopisujesz na następnej stronie.

Błędy osobno: 2>

ls nie_ma_takiego > wynik.txt

Czemu błąd i tak pojawił się na ekranie? Bo > przekierowuje tylko pierwszy głośnik, ten od normalnych rzeczy. Błędy idą drugim.

Głośniki mają numery. Normalny to 1, błędy to 2. Więc:

ls nie_ma_takiego 2> bledy.txt

Teraz błąd trafił do pliku bledy.txt, a ekran jest czysty.

Wszystko do jednego pliku

komenda > wszystko.txt 2>&1

Czytamy: normalne rzeczy do pliku wszystko.txt, a błędy (2) tam, gdzie idą normalne rzeczy (&1). Ten zapis wygląda jak szyfr, ale użyjesz go setki razy, zwłaszcza w skryptach uruchamianych w nocy.

W Bashu jest też krótsza wersja:

komenda &> wszystko.txt

Czarna dziura: /dev/null

komenda 2> /dev/null

/dev/null to specjalny plik, który pożera wszystko, co do niego wyślesz. Nic nie zapisuje, nic nie oddaje. Czarna dziura systemu.

Po co? Żeby uciszyć komunikaty, które Cię nie interesują. Jak wyciszenie grupy rodzinnej na WhatsAppie. Dalej piszą, ale Ty masz spokój.

Tylko ostrożnie. Wyciszone błędy to wciąż błędy. W lekcji o IT-horrorach była firma, w której maile o niedziałających backupach lądowały w czarnej dziurze. Skończyło się osiemnastoma godzinami awarii.

Czytanie z pliku: <

sort < zakupy.txt
wc -l < zakupy.txt

Strzałka w drugą stronę podaje plik komendzie jako wejście, jakbyś go wpisywał z klawiatury. W praktyce używa się tego rzadziej niż >, ale warto rozpoznać.

⚠ Typowy błąd

sort zakupy.txt > zakupy.txt

Chcesz posortować plik i zapisać go w tym samym miejscu. Wynik: pusty plik.

Dlaczego? Bo Bash najpierw przygotowuje przekierowanie, czyli czyści zakupy.txt, a dopiero potem uruchamia sort. Który dostaje pusty plik i grzecznie go sortuje.

To jak wyrzucenie garnka z zupą do zlewu, żeby nalać do niego tę samą zupę.

Rozwiązanie: zapisz do nowego pliku, a potem podmień.

sort zakupy.txt > zakupy_posortowane.txt
mv zakupy_posortowane.txt zakupy.txt

✎ Zadanie

Zrób plik dziennik.txt, do którego trzy razy dopiszesz datę i godzinę (komendą date). Potem uruchom ls na jednym pliku, który istnieje, i jednym, który nie istnieje, tak, żeby wynik trafił do ok.txt, a błąd do bledy.txt.

Pokaż rozwiązanie
date >> dziennik.txt
date >> dziennik.txt
date >> dziennik.txt
ls istnieje.txt nie_ma.txt > ok.txt 2> bledy.txt

W dziennik.txt są trzy linijki z datą, bo podwójna strzałka dopisuje. W ok.txt jest nazwa pliku, który istnieje, a w bledy.txt komunikat „No such file or directory”. Jedna komenda, dwa głośniki, dwa pliki. Jeśli w dzienniku masz jedną linijkę, to gdzieś użyłeś pojedynczej strzałki. Witaj w klubie.

Co dalej

Pliki to jedno. Ale co, jeśli wynik jednej komendy chcesz od razu podać drugiej? Bez plików po drodze. Następna lekcja to najważniejszy znak w całym Bashu. Pionowa kreska.