1 Programowanie skryptów powłoki 1. Wprowadzenie Skrypty są to programy pisane w języku programowania powłoki (np. bash) mogące wykonać zadania nie stępne dla zwykłych poleceń są zapisywane w pliku tekstowym. Powłoka jak każdy język programowania obsługuje zmienne, instrukcje warunkowe, pętle, dane wejściowe i wyjściowe. 2. Tworzenie i uruchamianie skryptów powłoki. Aby utworzyć skrypt należy pliku tekstowego wpisać polecenia tak, jakbyśmy wpisywali je w wierszu poleceń. Należy pamiętać, że przy pisaniu skryptów dla konkretnej powłoki w pierwszym wierszu należy zawrzeć komentarz w postaci: Spowoduje to, że jeżeli skrypt zostanie wywołany w innej powłoce, uruchomi ona nowy proces sh wykonania tego skryptu. Jest to konieczne, ponieważ instrukcje mają odmienną postać w różnych powłokach. Następnie należy zmienić plik w plik wykonywalny, czyli nadać prawo uruchamiania. chmod u+x skrypt Można przenieść skrypt katalogu znajdującego się na ścieżce wyszukiwania, wówczas będzie można uruchamiać go jak zwykłe polecenie: skrypt Jeżeli skrypt jest umieszczony w katalogu, który nie znajduje się na ścieżce wyszukiwania, wówczas w celu uruchomienia należy przed jego nazwą wpisać./ aby powłoka mogła go odnaleźć../skrypt Jeżeli w skrypcie w pierwszym wierszu nie określimy powłoki w jakiej ma być uruchamiany to możemy skrypt uruchomić na dwa kolejne sposoby: - przekazanie skryptu konkretnej powłoki, np.bash bash skrypt (powłoka bash zinterpretuje przekazany jej argument jako nazwę skryptu i uruchomi go.) - uruchomienie w aktualnej powłoce za pomocą.. skrypt
2 3. Zmienne W celu ustawienia wartości zmiennej pisze się jej nazwę, następnie znak równości i nową wartość. Te trzy elementy muszą się pojawiać razem bez żadnych odstępów i znaków tabulacji. np.: nazwa=wartość moje_dane= Jan Kowalski echo $moje_dane W celu usunięcia zmiennej należy wpisać po prostu jej nazwę i znak równości: nazwa= Jeżeli chcemy zobaczyć wartości wszystkich zmiennych powłoki wpisujemy set. Wszystkie wartości przechowywane w zmiennych są ciągami znaków. Jeżeli jednak są one numeryczne, wtedy w odpowiednim momencie będą traktowane jak liczby. Przy odwołaniu się zmiennej jej nazwę należy poprzedzić znakiem lara $ liczba= 10 expr $liczba + 5 15 Gdy w skrypcie powłoki odwołujemy się wartości zmiennej lub gdy zmienna posiada w swojej wartości znak spacji, brze jest zamknąć ją wewnątrz cudzysłowów unikniemy błędów podczas działania skryptu. nazwapliku= moj kument ls $nazwapliku ls: moj: No such le or directory ls: cument: No such le or directory Poprawnie będzie: nazwapliku= moj kument ls $nazwapliku moj kument
3 Jeżeli nazwa zmiennej przetwarzana jest zaraz obok innego ciągu znaków, należy zamknąć ją wewnątrz nawiasów klamrowych. Prawidłowo będzie: zmienna1= ksiazk echo Liczba mnoga od $zmienna1a to $zmienna1i Liczba mnoga od to (nie ma takich zmiennych jak $zmienna1a i zmienna1i) zmienna1= ksiazk echo Liczba mnoga od ${zmienna1}a to ${zmienna1}i Liczba mnoga od ksiazka to ksiazki 4. Wejście i wyjście Wyjście skryptu tworzone jest poleceniami echo i printf. echo Witam Witam wiek=21 printf Mam %d lat.\n $wiek Mam 21 lat. printf Mam %d lat.\n `expr 20+1` Mam 21 lat. Dane wejściowe pobierane są za pomocą polecenia read, które odczytuje jeden wiersz ze standarwego wejścia i zapisuje znalezione dane w podanych zmiennych. read zmienna1 zmienna2... Jeżeli poda się jedną zmienną zostanie w niej umieszczony cały wiersz. Jeżeli poda się dwie zmienne, początek wiersza pierwszego odstępu lub znaku tabulacji stanie się wartością pierwszej zmiennej, a reszta napisu po odstępie lub znaku tabulacji znajdzie się w drugiej zmiennej.
4 echo Podaj imie nazwisko i wiek read imie nazwisko wiek echo imie: $imie, nazwisko: $nazwisko, wiek: $wiek echo Podaj imie read imie echo Podaj nazwisko read nazwisko echo Podaj wiek read wiek echo imie: $imie, nazwisko: $nazwisko, wiek: $wiek 5. Wartości logiczne i kody powrotu W powłoce wartość 0 oznacza prawdę lub sukces, a każda inna wartość oznacza fałsz lub niepowodzenie. Dodatkowo każde polecenie w Linuksie w momencie zakończenia działania zwraca powłoki wartość całkowitą, nazywaną kodem powrotu lub statusem wyjścia. Tę wartość można odczytać za pomocą specjalnej zmiennej $? plik1.txt: Nazywam się Jan Kowalski Mieszkam we Włocławku. grep w Kowalski plik1.txt Nazywam się Jan Kowalski - znaleziono 1 wiersz 0 kod powrotu oznacza sukces. grep w Ala plik1.txt Nie znaleziono żadnego wiersza 1 kod powrotu oznacza niepowodzenie.
5 Test lub [... ] Polecenie test wbuwane w powłokę wyznacza wartość prostych wyrażeń logicznych, składających się z liczb i ciągów znaków, i ustawia swój kod powrotu na wartość 0 (prawda) lub 1 (fałsz) Lista typowych argumentów polecenia test, pozwalających na sprawdzanie parametrów, liczb całkowitych, ciągów znaków i plików. Testy plików Plik o podanej nazwie jest zwykłym plikiem Plik o podanej nazwie jest katalogiem Plik o podanej nazwie jest wiązaniem symbolicznym Istnieje i można go czytać Istnieje i daje się zapisać Istnieje i daje się uruchomić Plik ma niezerową długość Plik f1 jest nowszy niż plik f2 Plik f1 jest starszy niż plik f2 Testy ciągów znaków Napis nie jest pusty Napis ma zerową długość Napis ma niezerowa długość Napisy są identyczne Napisy nie są identyczne Testy wartości liczbowych Gdzie operator oznacza Równy Nierówny Większy niż Większy lub równy Mniejszy niż Mniejszy lub równy Łączenie i negowanie testów - operatory logiczne Negacja! Iloczyn i (AND) -a -f nazwapliku -d nazwapliku -L nazwapliku -r nazwapliku -w nazwapliku -x nazwapliku -s nazwapliku f1 nt f2 f1 ot f2 napis -z napis -n napis napis1 = napis2 napis1!= napis2 liczba1 operator liczba2 -eq -ne -gt -ge -lt -le Alternatywa lub (OR) -o Grupowanie (wyrażenie)
6 test 15 lt 7 - Czy 15 jest mniejsze od 7? 1 - Nie, nie jest. test n Witam - Czy ciąg znaków Witam ma niezerową długość? 0 - Owszem, ma Polecenie test posiada ść nietypowy alias: [... ], który nadaje się stosowania w instrukcjach warunkowych i pętlach. Poniższe testy są równoważne z powyższymi: [ 15 lt 7 ] - Czy 15 jest mniejsze od 7? 1 - Nie, nie jest. [ n Witam ] - Czy ciąg znaków Witam ma niezerową długość? 0 - Owszem, ma Uwaga: Należy pamiętać o tym, że pomiędzy znakami [ oraz ] a argumentami muszą być znaki spacji. True i false Powłoka bash posiada wbuwane polecenia true i false, ustawiające jedynie swój kod powrotu, odpowiednio na 0 i 1. true 0 false 1 Polecenia te przydają się w czasie tworzenia instrukcji warunkowych i pętli.
7 6. Instrukcje warunkowe. If Instrukcja if wybiera pomiędzy alternatywami, z których każda może posiadać własny złożony test. Najprostszą formą tej instrukcji jest if if polecenie - jeżeli kod powrotu polecenia będzie 0 ciało if [ `whoami` = root ] echo Jesteś superużytkownikiem Następną formą jest postać if-- if polecenie ciało1 ciało2 if [ `whoami` = root ] echo Jesteś superużytkownikiem echo Jesteś zwykłym użytkownikiem
8 Dostępna jest również postać if--elif-, która może posiadać wolną liczbę testów: if polecenie1 ciało1 elif polecenie2 ciało2 elif...... ciałon konto=1000 if [ `whoami` = root ] echo Jesteś superużytkownikiem elif [ $USER = root ] echo Być może jesteś superużytkownikiem elif [ $konto gt 100 ] echo Zapłać, a zostaniesz superużytkownikiem echo Jesteś zwykłym użytkownikiem
9 Case Polecenie case wylicza pojedynczą wartość i na jej podstawie przechodzi odpowiedniego kawałka kodu: Ogólna postać polecenia case wygląda następująco: case ciąg_znaków in wyr1) ciało1 wyr2) ciało2... wyrn) ciałon *) inne_ciało esac W tej postaci ciąg_znaków oznacza wolną wartość, najczęściej wartość zmiennej ($zmienna), wyr1 wyrn oznaczają wzorze porównania, znak gwiazdki (*) pełni rolę końcowego. Każdy zbiór poleceń musi być zakończony dwoma znakami średnika (). echo Co chciał(a)byś dzisiaj robić? read odpowiedz case $odpowiedz in jesc) echo Ok., idziemy coś zjeść spac) echo No to branoc *) echo Chyba nie rozumiem co masz na mysli. esac
10 echo Podaj znak read znak case $znak in X) echo $znak to X [aeiou]) echo $znak jest samogłoską [0-9]) echo $znak jest cyfrą *) echo Tego nie rozumiem esac 7. Pętle While Pętla while powtarza wykonanie zbioru poleceń tak długo, jak długo warunek jest prawdziwy. while polecenie ciało - póki kod wyjścia polecenia będzie zerem skrypt1: i=0 while [ $i lt 3 ] echo zmienna i to $i i=`expr $i + 1`./skrypt1 zmienna i to 0 zmienna i to 1 zmienna i to 2
11 Until Pętla until powtarza zbiór poleceń czasu, aż warunek stanie się prawdziwy: until polecenie ciało - póki kod wyjścia polecenia będzie niezerowy skrypt1: i=0 until [ $i gt 3 ] echo zmienna I to $i i=`expr $i + 1`./skrypt1 zmienna i to 0 zmienna i to 1 zmienna i to 2 zmienna i to 3 For Pętla for iteruje poprzez wartości z podanej listy: for zmienna in lista ciało skrypt1: for imie in Marcin Tomek Jacek echo $imie jest moim przyjacielem./skrypt1 Marcin jest moim przyjacielem Tomek jest moim przyjacielem Jacek jest moim przyjacielem
12 Pętla for skonale nadaje się przetwarzania list plików, np. wszystkich plików określonego typu, znajdujących się w aktualnym katalogu: for plik in *.c echo $plik jest plikiem Microsoft Worda Aby utworzyć pętlę nieskończoną, można użyć pętli while z warunkiem na true lub pętli until z warunkiem na false: while true echo petla na zawsze until false echo petla na zawsze Działanie takich pętli można zakończyć stosując polecenie break lub exit z odpowiednim warunkiem. 8. Break i Continue Polecenie break kończy działanie pętli, w której się znajduje. (bez break) skrypt1: for imie in Marcin Tomek Jacek echo $imie echo znowu echo koniec
13./skrypt1 Marcin znowu Tomek znowu Jacek znowu koniec A teraz wersja z poleceniem break: skrypt1: for imie in Marcin Tomek Jacek echo $imie if [ $imie = Tomek ] break echo znowu echo koniec./skrypt1 Marcin znowu Tomek Koniec tu pojawia się instrukcja break Polecenie continue wymusza w pętli przejście kolejnej iteracji. skrypt1: for imie in Marcin Tomek Jacek echo $imie if [ $imie = Tomek ] continue echo znowu echo koniec
14./skrypt1 Marcin znowu Tomek Jacek znowu koniec 9. Argumenty wiersza poleceń. Skrypty powłoki mogą przyjmować argumenty i opcje, tak jak i wszystkie inne polecenia w Linuksie. Wewnątrz skryptu tych argumentów można odwoływać się poprzez zmienne: $0 - przechowuje nazwę pod jaką ten skrypt został uruchomiony. $1-$9 parametry których można odwoływać się w skrypcie $# - liczba parametrów przekazanych skryptu. $@ - wszystkie parametry jako jeden napis są stępne w zmiennej. $* - lista w postaci odrębnych napisów. skrypt: echo Nazywam się $1 i pochodzę z $2./skrypt Kowalski Włocławka Nazywam się Kowalski i pochodzę z Włocławka Skrypt może kontrolować liczbę otrzymanych argumentów, sprawdzając zmienną $#: skrypt: if [ $# -lt 2 ] echo Bład $0: trzeba podać dwa argumenty echo Nazywam się $1 i pochodzę z $2./skrypt Adam Bład./skrypt: trzeba podać dwa argumenty
15 Aby iterować przez wszystkie argumenty przekazane skryptu, należy zastosować pętlę for razem ze specjalną zmienną $@, przechowującą wszystkie argumenty: for arg in $@ echo Znalazłem argument $arg 10. Zwracanie kodów powrotu exit. Polecenie exit kończy działanie skryptu i przekazuje powłoki podany kod powrotu. Tradycyjnie skrypty powinny zwracać wartość 0 w przypadku powodzenia, a 1 (lub inną wartość niezerową) w przypadku niepowodzenia. Jeżeli w skrypcie nie zostanie wywołane polecenie exit, wtedy kod powrotu automatycznie ustalany jest na wartość 0. skrypt: if [ $# -lt 2 ] echo Błąd: Należy podać dwa argumenty exit 1 echo Nazywam się $1 i pochodzę z $2 exit 0./skrypt Adam Bład: Należy podać dwa argumenty 1
16 Przykłady z powyższego opisu: Przykład1: echo Podaj imie nazwisko i wiek read imie nazwisko wiek echo imie: $imie, nazwisko: $nazwisko, wiek: $wiek Przykład2: echo Podaj imie read imie echo Podaj nazwisko read nazwisko echo Podaj wiek read wiek echo imie: $imie, nazwisko: $nazwisko, wiek: $wiek Przykład3: test 15 lt 7 Przykład4: test n Witam Przykład5: [ 15 lt 7 ] Przykład6: [ n Witam ] Przykład7: if [ `whoami` = root ] echo Jesteś superużytkownikiem Przykład8: if [ `whoami` = root ] echo Jesteś superużytkownikiem echo Jesteś zwykłym użytkownikiem
17 Przykład9: konto=1000 if [ `whoami` = root ] echo Jesteś superużytkownikiem elif [ $USER = root ] echo Być może jesteś superużytkownikiem elif [ $konto gt 100 ] echo Zapłać, a zostaniesz superużytkownikiem echo Jesteś zwykłym użytkownikiem Przykład10: echo Co chciał(a)byś dzisiaj robić? read odpowiedz case $odpowiedz in jesc) echo Ok., idziemy coś zjeść spac) echo No to branoc *) echo Chyba nie rozumiem co masz na mysli. esac Przykład11: echo Podaj znak read znak case $znak in X) echo $znak to X [aeiou]) echo $znak jest samogłoską [0-9]) echo $znak jest cyfrą *) echo Tego nie rozumiem esac Przykład12: i=0 while [ $i lt 3 ] echo zmienna i to $i i=`expr $i + 1`
18 Przykład13: i=0 until [ $i gt 3 ] echo zmienna I to $i i=`expr $i + 1` Przykład14: for imie in Marcin Tomek Jacek echo $imie jest moim przyjacielem Przykład15: for plik in *.c echo $plik jest plikiem Microsoft Worda Przykład16: for imie in Marcin Tomek Jacek echo $imie echo znowu echo koniec Przykład17: for imie in Marcin Tomek Jacek echo $imie if [ $imie = Tomek ] break echo znowu echo koniec
19 Przykład18: for imie in Marcin Tomek Jacek echo $imie if [ $imie = Tomek ] continue echo znowu echo koniec Przykład19: echo Nazywam się $1 i pochodzę z $2 Przykład20: if [ $# -lt 2 ] echo Bład $0: trzeba podać dwa argumenty echo Nazywam się $1 i pochodzę z $2 Przykład21: if [ $# -lt 2 ] echo Błąd: Należy podać dwa argumenty exit 1 echo Nazywam się $1 i pochodzę z $2 exit 0