===== Podstawy skryptów i filtrów ===== ==== Przygotuj się do laboratorium ==== * Przypomnieć sobie podstawy pracy z wybranym edytorem: **vi**, **emacs**, **nano**, **mcedit**, **joe**, **pico**, **jed**, **zile** * Przeczytać artykuł {{gjn-sh.pdf|Podstawy programowania skryptów Sh}} * Przeczytać artykuł {{gjn-bash.pdf|GNU Bash więcej niż Sh}} Dodatkowo przejrzeć wybrany / wszystkie (mogą się przydać do realizacji ćwiczeń w czasie tych i kolejnych zajęć): * //[[http://www.tldp.org/guides.html#abs|Advanced Bash-Scripting Guide]]// * Daniel Robbins - //Bash by example//: {{ bash-by-example-1.pdf |część 1}}, {{ bash-by-example-2.pdf |część 2}}, {{ bash-by-example-3.pdf |część 3}} (pierwotnie było dostępne [[http://www.ibm.com/developerworks/linux/library/l-bash/|pod tym adresem]]) * Mike G - //[[http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html|BASH Programming - Introduction HOW-TO]]// ==== Wiedza ==== === 1. Skrypty === Rola skryptów w administrowaniu: * pozwalają na łatwe zautomatyzowanie często wykonywanych zadań, * upraszczają administrowanie systemem, * umożliwiają dostosowanie narzędzi administracyjnych do swoich celów, * jak również stworzenie swoich własnych narzędzi. Czym są skrypty? * Skrypty są plikami zawierającymi programy w języku skryptowym. * Ten język jest najczęściej interpretowany, * w pewnym stopniu spowalnia to jego pracę, * ale ułatwia pisanie i uruchamianie. * Dostarcza wielu narzędzi "wysokopoziomowych". Języki i narzędzia do pisania skryptów - jest ich wiele, najpopularniejsze to: * Sh, * Csh/Ksh, * AWK, * Perl, * Tcl, * Python. Skrypt bash jest to: * plik tekstowy zawierający dowolne polecenia wykonywalne oraz wyrażenia języka bash. * Nawet prosta sekwencja poleceń, normalnie wydawanych w powłoce bash, zapisana w pliku staje się skryptem. === 2. Uruchamianie pliku skryptu === * Aby skrypt można było wykonywać bezpośrednio poprzez podanie nazwy, należy nadać mu atrybut wykonywalności (+x). * Wykonywalny plik tekstowy zawierający polecenia jest uruchamiany najczęściej przy pomocy powłoki logowania użytkownika. * Aby mieć pewność, że skrypt zostanie uruchomiony przy pomocy odpowiedniego interpretera, trzeba to w nim zapisać. * Pierwsza linia skryptu powinna mieć postać: #!/pelnasciezka/interpreter opcje Co w przypadku skryptów bash wygląda tak: #!/bin/bash * Od znaku hash (''#'') zaczyna się komentarze, sekwencja ''#!'' na początku pliku jest traktowana jako podanie interpretera. === 3. Przydatne narzędzia === Pisząc skrypty korzysta się z dowolnych poleceń Unixa. \\ Tym niemniej największą rolę odgrywają zestawy podstawowych narzędzi GNU. Proszę przeczytać manual do: * //[[http://manpages.ubuntu.com/manpages/precise/pl/man1/textutils.1.html|textutils]]// (zawiera opis narzędzi tekstowych takich jak **cat**, **nl**, **fmt**, **head**, **split**, **wc**, **md5sum**, **uniq**, **cut**, **tr** i in.) * //[[http://manpages.ubuntu.com/manpages/precise/pl/man1/fileutils.1.html|fileutils]]// (zawiera opis narzędzi plikowych, m.in. **ls**, **cp**, **dd**, **mkdir**, **chown**, **du**) * //[[http://manpages.ubuntu.com/manpages/precise/pl/man1/sh-utils.1.html|sh-utils]]// (zawiera opis narzędzi powłokowych, w tym **echo**, **printf**, **expr**, **tee**, **pwd**, **tty**, **whoami**, **date**, **seq**) Program **find** służy do wyszukiwania plików w systemie plików. Pozwala na zadawanie wielu kryteriów wyszukiwania, łączonych operatorami boolowskimi. Podstawowe użycie to: find sciezka -name nazwapliku -print Dodatkowo przydatne narzędzia to (ostatnie dwa zostaną bardziej szczegółowo omówione na kolejnych zajęciach): * **xargs** * **sed** * **awk** === 4. Podstawianie wyników pracy poleceń === To już wiesz, ale dla przypomnienia: podstawianie wyników poleceń w linii poleceń jest realizowane przez odwrotny apostrof, na przykład: > echo "To jest system" `uname` "na maszynie "`hostname` === 5. Język Sh === * Zmienne - podstawy * Dowolne polecenia dostępne w systemie * Zmienne i polecenia zewnętrzne - odwrócony apostrof, * Instrukcje warunkowe: **if**, **test** i **case**, * Funkcje * Parsing opcji z linii poleceń (przykład parser.sh) * Inne... Szczegóły w artykule {{gjn-sh.pdf|Podstawy programowania skryptów Sh}} ==== Ćwiczenia ==== === I. Find === Znaleźć przy pomocy find: * w katalogu ///usr/bin// wszystkie pliki o nazwie zaczynającej się na ''au'', * w katalogu ///tmp// wszystkie pliki należące do użytkownika ''root'', * w katalogu ///tmp// wszystkie pliki modyfikowane w ciągu ostatnich 24 godzin, * w katalogu ///tmp// wszystkie pliki zwykłe o uprawnieniach 700. === II. Podstawianie wyników pracy poleceń === Przy pomocy odwróconego apostrofu napisać polecenie przypisujące do zmiennej WYNIK: * aktualną datę, * napis o treści ''System pracuje od A, jest zalogowanych B uzytkownikow'', gdzie za ''A'' i ''B'' mają być wstawione odpowiednie informacje z polecenia **uptime** Przykład: > WYNIK="To jest system `uname` na maszynie `hostname`"; echo $WYNIK To jest system Linux na maszynie spk-ssh === III. Zaawansowane filtry === Napisać filtr, który: * wyświetli 7 pierwszych, posortowanych alfabetycznie, nazw plików o nazwie kończącej się na p znajdujących się w katalogu ///usr/bin//. * poda liczbę wszystkich plików zawierających w nazwie słowo ''ubuntu'', znajdujących się w katalogu ///usr/bin//. * zapisze do pliku ''spis'' posortowaną alfabetycznie listę użytkowników aktualnie zalogowanych z komputerów mających początek adresu IP: 149.156. * wybierze z 6 ostatnich linii pliku ''tekst'' te, które zawierają słowo ''coś'' i poda ilość występujących w nich znaków. (plik testowy należy stworzyć). === IV. Proste skrypty === Obejrzeć jak przebiega edycja w edytorach mcedit i GNU Emacs (w razie potrzeby włączyć: ''M-x sh-mode'' i ''M-x font-lock-mode'') Napisać poprawne skrypty, które wyświetlą: * aktualną datę, nazwę i czas pracy systemu, * spis zalogowanych użytkowników i spis sesji osoby uruchamiającej skrypt, * prawa dostępu do pliku podanego jako parametr z linii poleceń: ''skrypt plik'' i poda typ/opis tego pliku * do powyższego skryptu dopisać (najlepiej w postaci funkcji) kod sprawdzający czy właściciel pliku jest zalogowany, a jeżeli tak to wyświetli informacje o nim i jego otwarte sesje. * napisać skrypt (np. do użycia jako CGI) generujący dynamicznie stronę WWW (plik HTML) o tytule: ''To jest spis plików w katalogu KATALOG'' zawierającą spis i opis plików w podanym z linii poleceń katalogu, na każda pozycja spisu jest hiperłączem do odpowiedniego pliku. === V. Ciekawsze skrypty (dla zainteresowanych) === * Napisz skrypt, który dla każdego z plików podanych jako argumenty wywołania wyświetli w kolejnych liniach 3 najczęściej powtarzające się w nim słowa. * Napisz skrypt, który dla każdego z plików podanych jako argumenty sprawdzi (np. za pomocą polecenia ''file'') zastosowany na nim typ kompresji, a następnie zastosuje odpowiedni program do rozpakowania go. Jeżeli plik wejściowy nie jest spakowany, skrypt powinien wyświetlić ostrzeżenie i nie podejmować żadnej akcji względem tego pliku. * Napisz skrypt, który zarchiwizuje wszystkie pliki z Twojego katalogu domowego zmodyfikowane w przeciągu ostatnich 24 godzin (można użyć polecenia ''find''). * Napisz skrypt, który wyświetli po jednym wszystkie pliki z katalogu domowego większe niż 100kB. Dla każdego wyświetlonego pliku skrypt ma zapytać, czy użytkownik chce skompresować czy usunąć plik, postąpić zgodnie z jego wyborem, i przejść do następnego pliku. Skrypt ma zapisać do pliku nazwy i czas usunięcia usuniętych plików. * Napisz skrypt "bezpiecznego usuwania" ''srm.sh'', który podane jako argumenty pliki skompresuje (o ile już nie są skompresowane - należy to sprawdzić, np. przy pomocy polecenia ''file'') a następnie przeniesie je do folderu ''/home/user/trash''. Przy wywołaniu skrypt powinien sprawdzić folder ''trash'' i usunąć z niego pliku starsze niż 48 godzin. * Napisz skrypt, który rozwiązuje równanie kwadratowe (przyjmując jako argumenty parametry równania), użyj polecenia ''bc''. * Lista mailingowa. Napisz skrypt, używając polecenia ''mail'', który zarządza prostą listą mailingową. Skrypt ma za zadanie co miesiąc odczytywać treść zadanego pliku (podanego jako 1. argument) i rozsyłać go adresatom umieszczonym na liście w pliku podanym jako 2. argument. [[http://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/writingscripts.html|Więcej ciekawych zadań]]