===== 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ń]]