Skrypty to, krótko mówiąc, programy czytane przez
Transkrypt
Skrypty to, krótko mówiąc, programy czytane przez
Tworzenie, uruchamianie, podstawy - skrypty Skrypty to, krótko mówiąc, programy czytane przez interpreter linijka po linijce, nie wymagające kompilacji. Skrypty pisze się szybko, skrypty są krótkie, skrypty ułatwiają życie. Jak utworzyć sobie skrypt? touch skrypt //tworzymy pusty plik chmod +x skrypt //dodajemy możliwość wykonania (+x) do pliku A jak taki skrypt odpalić? ./skrypt A teraz pokrótce jak napisać skrypt: Po pierwsze potrzebujemy programu który wykona nasz skrypt (interpreter). Dlatego też, w pierwszej linijce musimy go wskazać, w dzisiejszych czasach będzie to: #!/bin/bash Czyli podstatwowa powłoka systemu. Dodam jeszcze, że wszystko napisane po '#' do końca linii jest komentarzem. Czas już najwyższy na przykład: "Napisz program który wypisze słowo podane w parametrze, obecny czas oraz nazwę użytkownika uruchamiającego skrypt" #!/bin/bash echo $1 date +%H:%M:%S whoami Linia pierwsza (przy cichym typowym dla informatyków założeniu, ze numerujemy od 0) zwraca nam pierwszy parametr jaki dostal skrypt ("$1"). Druga linia to odpowiednio sformatowana data (godzina:minuta:sekunda). Trzecia linia to whoami - czyli "kim jestem" polecenie które zwaraca nazwę zalogowanego usera. Co to znaczy że skrypt dostał parametr? No np. ./skrypt parametr1 parametr2 Skoro pierwszy parametr ukrywa się pod zmienną $1 to łatwo jest się domyślić, że reszta parametrów jest trzymana w zmiennych: $2, $3 itd. Jeżeli parametr nie istnieje to pod daną zmienną nic nie ma. A co jest w $0? Ano w $0 jest nazwa skryptu (i sposób jego wywołania). Czyli np. #!/bin/bash echo $0 Da nam: ./skrypt #[ENTER] ./skrypt 1 Jakie są jeszcze inne przydatne zmienne 'wbudowane'? $* - wypisze wszystkie parametry naraz $$ - zwróci numer procesu (PID) $# - zwróci ilość podanych parametrów Zmienne i operacje na zmiennych Jak działają w ogóle zmienne w tych skryptach? Wygląda to tak: Deklaracja/przypisanie: TEKST="dupa" LICZBA=666 PI=3.14 Wywołanie: echo $TEKST echo $LICZBA+$PI No i fajnie jest, ale co poniektórzy zauważą że $LICZBA+$PI nie da nam "669.14" lecz "666+3.14". Krótko mówiąc bash preferuje stringi. Słabo mu idzie liczenie, zaokrąglenia, składania obliczeń arytmetycznych jest mało przyjazna. Ale to tylko dlatego, że takie operacje nie są w praktyce prawie w ogóle potrzebne. Ale jezeli już trzeba... : JEDEN=222 DWA=444 echo $[ $JEDEN + $DWA ] #zwroci 666 echo $[ $JEDEN + 111 ] #zwroci 333 WYNIK=$[ JEDEN + DWA ] Jak widać, mało przyjaźnie. W ostatniej linijce jak łatwo się domyślić pod zmienną WYNIK została przypisana liczba 666. Rozpoznawane operacje arytmetyczne to: +, -, *, / ** - potęgowanie % - modulo ++ - pre i post inkrementacia / dekrementacja +=, -=, /= *= i operacje logiczne Należy pamietać o tym, że bash nie wykona niczego na liczbach zmiennoprzecinkowych (potraktuje je jako tekst). Kto nie bawił się wcześniej językami w stylu php, tego może dziwić, że bashowi wszystko jedno czy pod zmeinną jest string czy liczba. Wbrew pozorom jest to bardzo wygodne. Można kleić ze sobą wyrazy, zmienne tekstowe i liczbowe bez żadnych konwersji/rzutowań. JEDEN="du" 2 DWA="mny" TRZY="pa" CZTERY="n" PIEC=666 echo $JEDEN$DWA $TRZY$CZTERY #dumny pan echo $JEDEN$TRZY #dupa echo $JEDEN-$PIEC-$TRZY! #du-666-pa! Niektóre symbole (jak np '_') moga być wykorzystane w nazwie wiec trzeba na nie uwazac. Jezeli koniecznie chcemy je wypisac to tradycyjnie stostujemy \ (backslash). JEDEN="du" PIEC=666 echo $JEDEN_$PIEC # niepoprawnie - Bash bedzie szukal zmiennej $JEDEN_ (a takiej nie ma) echo $JEDEN\_$PIEC #poprawnie - wypisze: du_666 UWAGA! Popularny bład: JEDEN = 123 #zle - nie moze byc spacji pomiedzy znakiem = DWA=23 #dobrze Mało popularna, ale niekiedy przydatna jest możliwość pobrania danych od użytkownika już w trakcie działania skryptu (a nie jako parametr). #!/bin/sh echo Wpisz tekst: read TEST echo Napisałeś: echo $TEST Warunki Zacznijmy od if..then..elsa. Przykład: #!/bin/sh IF [ $# -le 2] ; THEN echo "Mniej niż 3 parametry" ELSE echo "3 parametry albo nawet więcej" FI Słowa kluczowe początkowo będą pisane dużymi literami dla poprawienia czytelności. Teraz śmieszna rzecz: warto zauważyć że polecenie IF jest zakończone swoją odwrotnąścią FI. Podobnie jest z kilkoma innymi poleceniami blokowymi. Druga rzecz, dziwne porównywanie. Oj dziwne - uważajcie na spacje, nawiasy i średniki które muszą być tak jak to jest w kodzie powyżej. Samo porównanie to '-le' znaczy 'less or equal' - mniejszy lub równy. Zaraz sobie wypiszemy część możliwości porównywania. Jak widzimy ilość 3 argumentów ($#) jest porównywana z liczbą 2 i na podstawie wyniku mogą zostać wypisane dwa rózne teksty. Możliwe jest oczywiście pominięcie kawałka z ELSE albo dodanie (ile chcemy) ELIF [ warunek ]; THEN. Krótko o dostępnych warunkach: Inty można porównywać na dwa sposoby: standardowo = (albo == - tutaj to jest to samo), !=, < , >, <=, >= używając takiego zapisu #!/bin/sh IF (($# < 2)); THEN echo "mniej niz 2" ELIF (($# > 2)); then echo "wiecej niz 2" ELSE echo "dwa" FI albo mniej standardowo(odpowiednio do tych na górze): -eq, -ne, -lt, -gt, -le, -ge używając takiego zapisu: #!/bin/sh IF [ $# -lt 2 ]; THEN echo "mniej niz 2" ELIF [ $# -gt 2 ]; then echo "wiecej niz 2" ELSE echo "dwa" FI Do stringów mamy: = (i == - tutaj to samo), !=,. <, >, -z (czy jest NULLem), -n (czy nie jest NULLem) Z plikami można robić mi. -e (sprawdza czy dany plik istnieje) Mamy jeszcze CASEa działa to tak: #!/bin/sh CASE $1 IN dupa) echo "Ale brzydko napisales" ;; 1) echo "Uczen bez jedynki to jak zolnierz bez karabinu" ;; *) echo Napisałeś $1;; ESAC To taki switch (jak w ansi c) w którym za zmienną brany jest pierwszy argument skryptu (w tym wypadku oczywiście). $1 jest prównywane z 'dupa' oraz '1' a jeżeli wszystko zawiedzie to wykonywana jest czynność domyślna *). Proszę zwrócić uwagę na ;; - podwójne średniki! Pętle 4 Skupimy się na dwóch pętlach: for'a i while'a. For jest bardzo przydatny bo można iterować po wszyskim. #!/bin/sh FOR uczelnie IN agh uj pk ar ap ae ; DO echo $uczelnie done Jak widać pod zmienną uczelnie są podstawiane kolejne nazwy z listy. Mogą to być również pliki z folderu, albo kolejni użytkownicy z listy itd. Pętle liczbową łatwiej zrobić while'm: #!/bin/sh i=0; while [ $i -le 10 ]; do i=$[i+1]; #inkrementujemy licznik echo $i done Widać, że warunki są tworzone identycznie jak w IFie. Reszta jest chyba oczywista. Można pomijać ten średnik po warunku ( ten przed 'do') jeżeli 'do' napiszemy w nowej linii. Średnik zachowuje się tak samo jak koniec linii. Cytowanie Mamy trzy rodzaje cytowania: "jedno", 'drugie' i `trzecie`. Czym się różnią pokazuje poniższy skrypt: #!/bin/sh $JEDEN="whoami" echo "$JEDEN" echo '$JEDEN' echo `$JEDEN` ./skrypt whoami $JEDEN kdzwinel " - działa tak że wypisuje wszystko ze środka interpretując zmienne ' - nie interpretuje zmiennych, porpostu wypisuje wszystko jako zwykły tekst ` - interpretuje zmienne i uruchamia polecenia zawarte w tekście ( teks po poleceniu zostanie potraktowany jako parametr) Cytowanie przydaje się wtedy gdy chcemy przekazać poleceniu parametr skłądający się z dwóch (lub więcej) wyrazów np ./skrypt "ZSZ WG" bez cytowania każde słowo zostało by potraktowane jako oddzielna zmienna. 5 Funkcje Funkcje tworzymy np. na sposób znany z c: #!/bin/sh funct () { echo "dupa" } funct #wywolanie Funkcje nigdy nic nie zwracają i nigdy nie mają określonych pomiedzy '(' a ')' parametrów jakie przyjmują. Jeżeli już koniecznie chcemy coś przekazać to wewnątrz funkcji działają $1 $2 itd, czyli funkcja zachowuje się jak 'skrypt w skrypcie'. #!/bin/sh funct () { echo $1 } funct "dupa" #wywolanie Funkcje mogą być deklarowane 'gdziebądź', ale są rozpoznawalne tylko w kodzie poniżej deklaracji. 6