Podstawy Basha według newbie
Dzisiaj nauczymy się pisać proste skrypty powłoki Bourne-Again Shell (jak to brzmi
). Ale od początku. Co to w ogóle jest skrypt powłoki (jakiejkolwiek)? Najogólniej mówiąc taki skrypt to mały program, który służy do automatyzowania pracy przy komputerze. Skrypty powłoki działają w odpowiednim interpreterze (powłoce). Dosyć suchej teorii… zgłodniałem od tej gadaniny, a naleśniki się skończyły…
1. Każdy programista zaczynał od “Hello World”. Oto kod:
#!/bin/bash
echo “Hello World”
#echo “Hello World 2″
Zapisujemy plik pod jakąkolwiek nazwą w katalogu domowym. U mnie to będzie ’skrypt’. Teraz otwieramy terminal i przechodzimy do katalogu domowego. Wypadałoby nadać naszemu skryptowi prawa do wykonywania. Wystarczy wydać polecenie:
chmod +x skrypt
Teraz możemy sprawdzić efekt naszej pracy. Wydajemy polecenie:
./skrypt
I oto wyświetla się napis. Zanalizujmy kod. Linia 1. informuje system o tym, z jakiego interpretera ma korzystać. Jest taka sama dla każdego skryptu Basha i musi się w nim znaleźć. Linie 2-3 zawierają instrukcje ‘echo’ służące do wyświetlania łańcucha znaków podanego w cudzysłowach. Ale, jak zapewne zauważyliśmy 3. linia nie jest brana pod uwagę. Winę za to ponosi znak ‘#’ na początku linii. Mówi on interpreterowi, że cała linia jest komentarzem i nie ma być interpretowana. Przydatne w sytuacji gdy chcemy np. wprowadzić opis do kodu, lub zablokować tymczasowo jego część. Mała rzecz a cieszy xD
2. Oczywiście wyświetlanie tekstu na wyjściu to nie jedyna możliwość skryptów Basha. Posłużmy się zmiennymi i tablicami. Kod? Oto on:
#!/bin/bash
A=10
B=15
echo “Suma A i B:” $[$A +$B]
Nic szczególnego. Na wyjściu pokazuje się suma A i B. Owe A i B to zmienne. Deklaracja zmiennej to po prostu NAZWA_ZMIENNEJ=WARTOŚĆ. Niekoniecznie dużymi literami, po prostu tak mi łatwiej. Linia 4. liczy sumę wartości owych zmiennych. I tu pojawia się kilka udziwnień… Odwołanie się do jakiejkolwiek zmiennej wymaga użycia dolara ($) przed jej nazwą. A przy operacjach matematycznych jest jeszcze gorzej. Każda operacja arytmetyczna/logiczna wymaga użycia kolejnego dolara i nawiasów kwadratowych ($[...]). Gdyby nie one, na wyjściu mielibyśmy ‘10+15′ zamiast ‘25′. Warto jeszcze zaznaczyć, że Bash obsługuje większość operacji matematycznych znanych z C++ (dodawanie, odejmowanie, dzielenie, mnożenie, Usprawmy trochę ten prymitywny kalkulatorek tak, abyśmy mogli sami wpisać liczby do dodania. Do tego służy instrukcja ‘read’. Oto kod:
#!/bin/bash
echo -n “Podaj A:”
read A
echo -n “Podaj B:”
read B
echo “Suma A i B:” $[$A +$B]
W linii 2. jest instrukcja ‘echo’ z parametrem ‘-n’. Co oznacza ten parametr? Oznacza on tyle, żeby po wyświetleniu tekstu nie było przejścia do następnej linii. W linii 3. natomiast mamy instrukcję ‘read’, która pobiera wartość do zmiennej A. Linie 4-5 powtarzają się, z tym że dla zmiennej B. Linia 6. wyświetla sumę podanych liczb
Teraz słowo o obiecanych tablicach. Tablica to jakby zestaw zmiennych o tej samej nazwie. Aby je odróżnić stosuje się indeksy. Pewnie i tak nie wiesz o co chodzi, ale zaraz będziesz wiedział. Kod:
#!/bin/bash
TABLICA=(Debian “Ubuntu Linux” “Arch Linux”)
echo ${TABLICA[0]}
echo ${TABLICA[1]}
echo ${TABLICA[2]}
Linia 2. jest deklaracją tablicy. Deklarowanie jest akurat proste, wystarczy jako wartość podać kilka tychże w nawiasach. Cudzysłowu używamy, gdy wartość zmiennej tablicowej zawiera znak spacji (dla oddzielenia rco jest cor1;). Linie 3-5 stanowią odwołania do zmiennych tejże tablicy. Trochę o indeksach: indeks to numer identyfikacyjny elementu tablicy. Chcąc odwołać się do danego elementu musimy użyć indeksu.
3. Dobrnęliśmy do instrukcji warunkowych… żeby nie przedłużać:
#!/bin/bash
A=4
if (($A < 4)); then
echo “mniej niz 4″
elif (($A > 4)); then
echo “wiecej niz 4″
else
echo “rowne 4″
fi
Instrukcja warunkowa polega na sprawdzeniu warunku i (zależnie od tego czy wynik jest negatywny czy pozytywny) wykonaniu czynności. Deklaracja wygląda tak: ‘if ((…warunek…)); then’. Możliwe do sprawdzenia warunki to: <, >, <= (mniejsze lub równe), >= (większe lub równe), == (równe), != (nierówne). Linia 3. sprawdza warunek rczy A jest mniejsze od 4r1;. Jeśli tak wypisuje odpowiedni łańcuch znaków (linia 4.). Jeśli nie, omija fragment kodu do momentu wystąpienia ‘elif’/'else’. ‘elif’ pozwala sprawdzić kolejny warunek (jak w linii 5.). Natomiast ‘else’ działa gdy wszystkie warunki dadzą negatywny wynik. ‘fi’ kończy całą instrukcję warunkową. Inną, użyteczną myślę instrukcją jest ‘case’. Działa ona na zasadzie przełącznika. Oto kod:
#!/bin/bash
read A
case $A in
1) echo “jeden” ;;
2) echo “dwa”;;
3) echo “trzy”;;
*) echo $A;;
esac
W linii 2. odbierana jest wartość zmiennej A. To już powinieneś wiedzieć. W linii 3. znajduje się instrukcja ‘case’. Jej składnia wygląda tak: ‘case $ZMIENNA in’. Następnie w liniach 4-7 są możliwe wyniki warunku. Zmienna $A porównywana jest z wartościami przed ‘)’. Jeżeli wynik jest pozytywny, wykonuje polecenie podane po ‘)’. Jeżeli nie, pomija je. Linia 7. stanowi polecenie, które zostanie wywołano gdy inne warunki dały wynik negatywny (taki ‘else’). ‘esac’ z ninii 8. kończy instrukcję ‘case’.
4. Zajmijmy się teraz pętlami… nie, nie takimi na szyję
Pętle służą do powtarzania czynności zawartych w nich. Przykład? Oto i on:
#!/bin/bash
i=0;
while (( $i < 10 )); do
i=$[i+1];
echo $i
done
Pętla wykonuje się, dopóki zmienna ‘i’ jest mniejsza od 10. W linii 3. następuje deklaracja pętli i wygląda ona podobnie do ‘if’. Składnia: ‘while (( …warunek…)); do’. W linii 4. zmienna ‘i’ jest inkrementowana (czyli jej wartość wzrasta o 1), po czym w linii 5. wyświetlana jest jej wartość. Linia 6. kończy pętlę. Ciekawostką jest fakt, że cała pętla wykonuje się jeszcze raz, dopóki warunek podany w pętli nie da wyniku negatywnego. W tym przypadku dopiero gdy ‘i’ będzie równe 10 pętla zakończy się. Kolejną użyteczną pętlą jest ‘for’. Służy ona do operacji na kolejnych elementach tablicy. Prosty i pyszny przykład:
#!/bin/bash
for wina in “leśny dzban” “fajrant” “komandos” “wino-wino” “żulowe mocne”; do
echo $wina
done
Aż sobie smaka narobiłem. Linia 3. stanowi pętlę na tablicy ‘wina’ zawierającej nazwy tych znakomitych trunków
Pętla będzie wykonywana dla każdego kolejnego elementu tej tablicy. To znaczy, że najpierw na pierwszym, potem na drugim itd. Linia 4. o tym świadczy: z każdym przebiegiem pętli wyświetla inny element. ‘done’ kończy całą zabawę.
5. Nadeszła chwila na coś o cytowaniu, czyli o konwencjach stosowanych przy łańcuchach znaków. Najpierw standardowe cytowanie czyli cudzysłów:
#!/bin/bash
A=”Shell”
echo “Bourne-Again $A”
Stosując cudzysłów chcemy, aby interpretowano w nim zmienne. W podanym przykładzie wynikiem będzie “Bourne-Again Shell”. Spróbujmy zamienić cudzysłów na pojedynczy:
#!/bin/bash
A=”Shell”
echo ‘Bourne-Again $A’
Teraz zmienna A nie będzie interpretowana. Należy o tym pamiętać pisząc skrypty, by uniknąć błędów. Teraz nieco o szczególnie przydatnym rodzaju cytowania. Stosując znak ‘`’ (klawisz tyldy) możemy wywoływać polecenia dostępne w interpreterze. Chociażby zmienić hasło usera, pokazać informacje o systemie, uruchomić figleta lub mencodera z podanymi parametrami itp. To właśnie stanowi potęgę Basha. Skrypty wywołujące inne programy to niezwykłe narzędzia. Prosty przykład wykorzystujący program uname do pokazania informacji o systemie:
#!/bin/bash
echo “System:” `uname -o`
echo “Kernel:” `uname -r`
echo “Platforma:” `uname -m`
echo “Nazwa komputera w sieci:” `uname -n`
Działanie jest proste. W każdej z linii 2-5 wyświetlany jest tekst, po czym następuje wykonanie polecenia podanego między ‘`’.
6. Nasze skrypty mogą przyjmować parametry z zewnątrz. Dzięki temu możemy wprowadzać dane już podczas wywołania skryptu. Kod? Proszę:
#!/bin/bash
echo “Wywołałes skrypt z parametrem $1″
Zapiszmy ten skrypt i wywołajmy go z parametrem “Parametr!”. Wydajemy w tym celu polecenie:
./skrypt “Parametr!”
I wyświetla nam się ładny napis “Wywołałeś skrypt z parametrem Parametr!”. W linii 2. wywołujemy zmienną $1, która przyjmuje wartość pierwszego parametru. Jak łatwo się domyślić, zmienna $2 przyjmie wartość drugiego, $3 – trzeciego itd. Zmienna $0 odpowiada za nazwę skryptu i sposób jego wywołania. W tym przykładzie przyjęła by wartość ‘./skrypt’.
Uff. Dobrnęliśmy do samego końca tegoż tutoriala. W epilogu pozostaje mi powiedzieć, że chciałem być newbie-friendly, ale czy mi wyszło oceń sam
Nie poruszyłem tutaj kilku zagadnień, mam nadzieje, że łebski z Ciebie gość i sobie doczytasz. Za błędy przepraszam. Następnym razem opiszę kilka ciekawych sztuczek i skryptów. I… miłego kodzenia