Składnia warunku:
if wyrażenie;
then
instrukcje
fi
Gdy wyrażenie jest prawdziwe (zobacz wyrażenia warunkowe) wówczas wykonywane są instrukcje pomiędzy słowem then i fi.
Przykład:
#!/bin/bash if [ $# -eq 0 ]; then echo "Nie podałeś żadnych argumentów " fi exit 0
Bardziej rozbudowane wyrażenie warunkowe:
if wyrażenie;
then
instrukcje
else
instrukcje 2
fi
Instrukcje zawarte w bloku rozpoczynającym się od else są wykonywane gdy wyrażenie nie jest spełnione. Np.:
#!/bin/bash if [ $# -eq 0 ]; then echo "Nie podałeś żadnych argumentów. " echo "Podaj liczbe calkowita " echo "Sprobuj: $0 liczba" exit 1 fi if [ $1 -lt 0 ]; then echo Liczba $1 jest mniejsza od zera else echo Liczba $1 jest wieksza lub równa 0 fi exit 0
Przykład - skrypt o nazwie rzut.sh wyświetlający słowo Orzeł lub Reszka z prawdopodobieństwem 1/2.
#!/bin/bash if [ $(($RANDOM%2)) -eq 1 ]; then echo "Reszka" else echo "Orzeł" fi
Przykład - skrypt o nazwie podglad.sh który dla danego w argumencie pliku wyświetla jego zawartość za pomocą less, zaś jeżeli podany argument jest nazwą katalogu wówczas wyświetlana jest zawartość tego katalogu.
#!/bin/bash if [ $# -lt 1 ]; then echo "Podaj plik lub katalog jako argument." echo "Uzycie: $0 plik" exit 1 fi if [ -f $1 ]; then less $1 else if [ -d $1 ]; then ls -l $1 else echo "Blad: $1 nie jest plikiem ani katalogiem" fi fi
Pętla for wykonuje zadane instrukcje tyle razy ile jest elementów na podanej liście.
for zmienna in lista;
do
instrukcje
done
W każdej iteracji kolejny element z listy jest podstawiany do zmiennej.
Przykład użycia w linii komend:
$ for f in *; do echo "Plik $f zajmuje $(du -sb $f) bajtow"; done
dla każdego pliku w bieżącym katalogu wyświetli komunikat o ilości zajmowanych bajtów.
Przykład: skrypt zamieniający w nazwach plików duże litery na małe.
#!/bin/bash if [[ $# -eq 0 || $1 == "-h" || $1 == "--help" ]]; then echo "Uzycie: $0 [-h] plik..." echo "Zamienia w nazwach podanych plikaow duze litery na male (np. Plik.TXT na plik.txt)." echo "Opcja -h wyswietla pomoc." exit 1 fi for plik in $* do if [ -e $plik ]; then nowy_plik=$(echo $plik | tr ’[A-Z]’ ’[a-z]’) if [ $plik != $nowy_plik ]; then echo "Zamieniam: $plik na $nowy_plik" mv $plik $nowy_plik fi else echo "Blad: $plik - nie ma takiego pliku" fi done
Powłoka Bash umożliwia także użycie pętli for znanej z języka C.
for (( wyrażenie1 ; warunek ; wyrażenie2 ))
do
instrukcje
done
Wszystkie instrukcje są wykonywane dopóki warunek jest spełniony.
Początkowe wyrażenie1 jest uruchomione tylko raz przed rozpoczęciem pętli, zazwyczaj służy do zainicjowania zmiennych.
Końcowe wyrażenie2 jest wykonywane na końcu każdej iteracji, zazwyczaj używane jest do zwiększenia (lub zmniejszenia) pewnego licznika.
Przykład: skrypt wyznaczający silnię
#!/bin/bash if [[ $# -eq 0 || $1 == "-h" || $1 == "--help" ]]; then echo "Uzycie: $0 [-h] liczba" echo "Oblicza silnie podanej liczby." echo "Opcja -h wyswietla pomoc." exit 1 fi silnia=1; for (( i=2 ; i<=$1 ; i++ )) do let silnia=silnia*i; done echo "Silnia wynosi $silnia"
Przykład: wielokrotne losowanie kostką
#!/bin/bash if [[ $1 == "-h" || $1 == "--help" ]]; then echo "Rzut kostka" echo "Uzycie: $0 [-h] liczba" echo "Wyswietla wynik rzutu kostka powtorzenoge zadana liczbe razy." echo "Opcja -h wyswietla pomoc." exit 1 fi ile=1 if [ $# -gt 0 ]; then ile=$1 ;fi for (( i=1 ; i<=ile ; i++ )) do wynik=$(($RANDOM%6+1)) echo $wynik done
Składnia pętli while:
while warunek
do
instrukcje
done
Podane instrukcje są wykonywana dopóki warunek jest prawdziwy.
Przykład - stoper, odlicza sekundy od rozpoczęcia działania skryptu:
#!/bin/bash if [[ $1 == "-h" || $1 == "--help" ]]; then echo "Stoper - po prostu uruchom bez argumentow." echo "Ctrl+C konczy odliczanie." echo "Opcja -h wyswietla pomoc." exit 1 fi let s=0 while true; do echo $s sleep 1 let s++ done
Instrukcja true zwraca zawsze wartość logiczną prawda. Analogicznie false daje odpowiedź negatywną.
Instrukcja case pozwala na wykonanie wybranych instrukcji w zależności od wartości przyjmowanej
przez pewną zmienną. Działanie bardzo podobne do instrukcji if jednak często wygodniejsze w użyciu, zwłaszcza gdy
mamy więcej niż dwie możliwości do wyboru.
case zmienna in
wartość_1)
instrukcje 1
;;
wartość_2)
instrukcje 2
;;
…
*)
instrukcje
;;
esac
Przykład - skrypt wyświetlajązy menu:
#!/bin/sh while true do clear echo "============================" echo "[1] Wyświetl dzisiejszą datę" echo "[2] Wyswietl listę plików w bierzącym katalogu" echo "[3] Pokarz kalendarz" echo "[4] Pokarz listę zalogowanych uzytkownków" echo "[5] Zakończ" echo "============================" echo -n "Wybierz liczbę [1-5]: " read akcja case $akcja in 1) echo "Dzisiejsza data: $(date)" ;; 2) echo "Lista plików w katalogu $(pwd)" ls -l ;; 3) cal ;; 4) echo "Lista zalogowanych" ; who ;; 5) echo "Do widzenia" exit 0 ;; *) echo "Blad!!! Proszę wybrać wartość 1,2,3,4, lub 5"; esac echo "Wciśnij klawisz Enter" read done
Instrukcja exit kończy działanie skryptu.
Liczba całkowita umieszczona po instrukcji exit jest zwracana do powłoki jako wynik działania skryptu.
W przypadku poprawnego wykonania skrypt powinien kończyć się wyrażeniem exit 0. Gdy skrypt nie został wykonany poprawnie wówczas po słowie exit wstawiamy dowolną liczbę różną od zera (wartość zwracanej liczby może w ten sposób sygnalizować rodzaj błędu który spowodował niepoprawne wykonanie skryptu). Wartość zwracana po słowie exit umieszczana jest w zmiennej $?.
Instrukcja read pozwala wczytać linie tekstu do podanej zmiennej.
Przykład:
#!/bin/bash echo Podaj imie i nazwisko read dane echo Witaj $dane
Instrukjca read użyta w pętli while umożliwia czytanie tekstu z pliku linia po linii, np.:
#!/bin/bash echo Podaj nazwe pliku do wyswietlenia read plik if [ ! -r $plik]; then echo "Nie moge czytac z pliku $plik" exit 1 fi while read linia do echo $linia done < $plik
W powłoce bash możliwe jest definiowanie funkcji, czyli wyodrębnionych podprogramów oznaczonych pewną unikatową nazwą.
nazwa_funkcji( )
{
instrukcje do wykonania
return
}
Funkcja wykonywana jest w momencie gdy pojawi się wywołanie jej nazwy.
Przykład:
#!/bin/sh pomoc() { echo "Wyswietla liste i liczbe zalogowanych uzytkonikow" echo "Opcje:" echo "-h pomoc" echo "-l liczba zalogowanych użytkoników" echo "-w lista zalogowanych użytkoników" return } # lista niepowtarzajacych sie nazw zalogowanych uzytkownikow lista() { users=( $(who | cut -f 1 -d ’ ’ | sort | uniq ) ) return } case $1 in "-h") pomoc ;; "-l") lista echo "Liczba zalogowanych uzytkonikow = ${#users[*]} " ;; "-w") lista echo "Lista uzytkownikow: ${users[*]}" ;; *)Ψpomoc ;; esac
Do funkcji możemy przekazać argumenty dodając je przy wywołaniu po nazwie funkcji. Kolejne argumenty umieszczone są w zmiennych $1, $2, $3, itd. Ilość argumentów dana jest poprzez $#, lista wszystkich argumentów zawarta jest w zmiennej $* a zmienna $0 zawiera nazwę funkcji.
#!/bin/sh funkcja() { echo "Argumenty funkcji $*" echo "Ilość argumentów funkcji $#" return 0 } echo "Argumenty skryptu $*" echo "Ilość argumentów skryptu $#" echo Uruchamiam funkcje z argumentami: raz dwa trzy funkcja raz dwa trzy echo Uruchamiam funkcje z argumentami będącymi nazwami plików z bierzącego katalogu funkcja * exit 0
Zmienne użyte wewnątrz funkcji maja zakres globalny, tzn. ich wartość jest dostępna poza funkcją (np. zmienna users z pierwszego przykładu w tym paragrafie).
Chcąc ograniczyć czas życia zmiennej wyłącznie do obszaru zdefiniowanego przez funkcję należy zadeklarować zmienną poprzedzając ja instrukcją local.
Używanie zmiennych lokalnych może uchronić przed wieloma trudnymi do wykrycia błędami, więc gdzie tylko jest to możliwe, wewnątrz funkcji należy je stosować.
Przykład:
#!/bin/sh funkcja() { local zmienna="Zmienna lokalna" echo "Jestem wewnątrz funkcji" echo "zmienna=$zmienna" return 0 } zmienna="Zmienna globalna" echo "Zmienna=$zmienna" funkcja echo "Zmienna=$zmienna" exit 0