Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Zrozumieć powłokę tekstową - niezwykła moc potoków

System Linux i każdy UNIX ma jedną, wielką zaletę, o której pisałem już w poprzednich wpisach. Otóż większość plików, które mają znaczenie administracyjne, to proste pliki tekstowe nadające się do edycji bez pomocy specjalizowanych narzędzi. Wystarczy prosty edytor tekstu, jak np. notatnik. Wszystkie pliki konfiguracyjne znajdują się w katalogu /etc, w którym każdy program ma własny katalog z plikami konfiguracyjnymi. Pliki te, tak jak już wcześniej wspomniałem, pisane są otwartym tekstem.

Ale jaki to ma związek z potokami?
Skoro cała konfiguracja systemu to pliki tekstowe, a powłoka bash i system Linux zawierają wiele narzędzi do ich edycji, tzn. że z poziomu terminala jesteśmy w stanie zrobić dosłownie wszystko. W poprzednich artykułach pisałem już o strumieniach (STDOUT, STDIN, STDERR). Ich znajomość pozwala nam na odpowiednie skierowanie danych wejściowych i wyjściowych wszystkich programów. Ale czy da się wykorzystać dane wyjściowe programu A jako dane wejściowe programu B? Ależ oczywiście, że TAK. I jaka w tym niezwykła moc? - czytajcie dalej.

Operator potoku "|" jest niezwykły. Potrafi przekierować STDOUT jednego programu do STDIN drugiego bez konieczności zapisywanie w międzyczasie jakikolwiek plików czy zmiennych. Zamiast rozpisywać się na jego temat pokażmy jak działa. Zatem wracamy do naszego pliku plik.txt i tym razem zaszalejmy i dodajmy do niego dwie linie tekstu.

echo dobreprogramy.pl to moja ulubiona strona internetowa > plik.txt echo HotZlot to najlepsza impreza IT >> plik.txt(pomijam fakt, że te dwie linie można dodać jednym poleceniem, ale nie chcę robić początkującym wody z mózgu)

Zanim jednak skorzystamy z operatora potoku, to musimy ustalić co z tym tekstem chcemy zrobić. Dlatego muszę czytelnikom przybliżyć kila narzędzi. Zaczniemy od grep

grep - bardzo proste narzędzie, którego zadaniem jest wyszukiwanie w tekście określonego ciągu znaków (obsługuje wyrażenia regularne), a wynikiem jego działania najczęściej jest wiersz z tekstu zawierający wyszukiwaną frazę.

Zatem wyszukajmy w naszym pliku słowa HotZlot:chomik@zhp:~$ cat plik.txt | grep HotZlot HotZlot to najlepsza impreza ITJak widać najpierw za pomocą polecenia cat postanowiliśmy wyświetlić zawartość pliku plik.txt. Następnie STDOUT polecenia cat został za pomocą operatora potoku "|" skierowany bezpośrednio na STDIN polecenia grep, którego zadaniem jest wyszukanie frazy HotZlot. W wyniku mamy tylko wiersz zawierający szukane słowo.

Na pierwszy rzut oka do niczego nam się to nie przyda, ale jak poznamy np. narzędzie cut to zaczyna się robić ciekawiej.

cut - narzędzie służące do wyłuskiwania potrzebnych danych z wiersza. A zasadę jego działania wytłumaczę na przykładzie polecenia ping.

chomik@zhp:~$ ping -c 2 dobreprogramy.pl PING dobreprogramy.pl (194.0.171.150) 56(84) bytes of data. 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=121 time=32.0 ms 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=121 time=32.0 ms (DUP!) 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=121 time=32.0 ms (DUP!) 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=2 ttl=121 time=28.0 ms --- dobreprogramy.pl ping statistics --- 2 packets transmitted, 2 received, +2 duplicates, 0% packet loss, time 1004ms rtt min/avg/max/mdev = 28.000/31.000/32.000/1.732 msZałóżmy, że do naszego skryptu potrzebujemy pobrać dane o średnim czasie odpowiedzi danego serwera - w tym wypadku dobreprogramy.pl. To ta podkreślona wartość wyświetlona w ostatniej linii.rtt min/avg/max/mdev = 28.000/31.000/32.000/1.732 msBędziemy to robić dziennie tysiąc razy, więc ręczne przepisywanie nie wchodzi w grę. Jak to wyłuskać?
Najpierw z wyniku naszego polecenia ping bierzemy tylko ostatnią linię. Łatwo ją wydobyć poleceniem grep bo zawsze w niej znajduje się słowo rtt (round trip time). chomik@zhp:~$ ping -c 2 dobreprogramy.pl | grep rtt rtt min/avg/max/mdev = 28.000/31.000/32.000/1.732 msTeraz zastosujemy magię polecenia cut. Żeby wydobyć interesujące nas dane, musimy powiedzieć komputerowi jak ma je znaleźć. Można to zrobić za pomocą znaków separatora pól. Pomiędzy słowami są znaki spacji. Teraz wystarczy powiedzieć powłoce po którym znaku spacji są interesujące nas dane. Wyobraźmy sobie, że każdy tekst pomiędzy znakami spacji to kolumna. W takim razie w pierwszej kolumnie będzie "rtt", w drugiej "min/avg/max/mdev", w trzeciej "=", a w czwartej "28.000/31.000/32.000/1.732". Zatem możemy zawęzić wynik tylko do czwartej kolumny.chomik@zhp:~$ ping -c 2 dobreprogramy.pl | grep rtt | cut -d' ' -f4 28.000/31.000/32.000/1.732Czyli tak:
1. ping ping -c 2 dobreprogramy.pl - wykonuje polecenie
2. grep rtt - wycina ostatnią linie wyniku
3. cut -d' ' -f4 - wycina czwartą kolumnę. Przełącznikiem "-d" definiujemy separator pola - tutaj jest to spacja; a "-f" definiuje numer kolumny

Ale nas dalej interesuje tylko to 31.000, więc potok puszczamy dalej i znów skorzystajmy z polecenia cut, ale tym razem jako separator pola użyjemy znaku "/".chomik@zhp:~$ ping -c 2 dobreprogramy.pl | grep rtt | cut -d' ' -f4 | cut -d'/' -f2 31.000Teraz wynikiem jest interesująca nas liczba. Możemy ją zapisać do zmiennej, do pliku, lub przekierować gdzieś dalej.

Teraz pewnie połowa z Was zachodzi w głowę do czego to się może przydać. Ja nie lubię podawać gotowego rozwiązania na tacy, dlatego drodzy młodzi administratorzy dostaniecie ode mnie zadanie, aby w komentarzu opisać co będzie wynikiem poniższego polecenia i co dzięki temu możemy uzyskać. Potrzebujecie do tego Linuksa (Ubuntu, bo w innych dystrybucjach plik z logami może mieć inną nazwę), powłokę bash, uprawnienia administratora lub prawo do odczytania pliku /var/log/auth.log. cat /var/log/auth.log | grep 'Failed password for root' | cut -d' ' -f12 | uniq

Przestrzegam, że nieświadome uruchamianie tego polecenia może Wam coś popsuć, dlatego robicie to na własną odpowiedzialność

Komentarze

0 nowych
  #1 05.07.2010 19:30

można w ten sposób podmienić jakiś tekst w pliku?

Chomik   4 #2 05.07.2010 21:11

Nie wiem czy masz na myśli to, że możesz przypadkiem coś podmienić w pliku auth.log, czy może pytasz ogólnie czy za pomocą potoków można edytować tekst.
Zatem odpowiem na oba:
1. Stosując polecenie
cat /var/log/auth.log | grep 'Failed password for root' | cut -d' ' -f12 | uniq
nie można niczego zepsuć, bo wynik nigdzie nie jest zapisywany, a tylko wyświetlany na ekranie. Jeżeli ktoś by na końcu nieświadomie dopisał przekierowanie gdzieś strumienia to może sobie narobić kłopotów.
2. Tekst oczywiście można podmieniać w pliku, ale to tego używa się innych narzędzi. Polecam zapoznać się z narzędziem "awk" oraz "sed" (ang. Stream EDitor). Są to narzędzia często używane zamiennie. Osobiście na początek polecam sed'a. Działa na strumieniach, potokach itp.

  #3 05.07.2010 22:07

Ciekawe, dobrze się czyta, jeśli chodzi o konkretne wyniki np do zrzutu w pliku super, ale na co dzień do debugu w sumie grep wystarcza. Pozdrawiam, czekam na więcej.

Grzegorz®   6 #4 06.07.2010 08:34

Nie jestem użytkownikiem Linuksa. Jeśli jednak chodzi o przetwarzanie potokowe, to było już w Amidze. Nic zresztą w tym dziwnego bo pewne rozwiązania AmigaOS były wzorowane na UNIX-ie. Ciekawe zresztą, że o ile na Amidze z Shell-a korzystałem dość często, to obecnie pracując na Windows robię to raczej sporadycznie.

Zaś zmieniając nieco temat, to ani pod Windows ani pod Linuksem nie spotkałem się z rozwiązaniem w rodzaju ARexx-a. Trochę szkoda, że taka fajna idea gdzieś zginęła.

spunky   2 #5 06.07.2010 10:43

Cała seria "Zrozumieć powłokę tekstową" to bardzo dobre wpisy. Mam nadzieję, że będzie ich dużo więcej. Pozdro