Zmienne definiuje się przy pomocy polecenia: set (zmienne lokalne), setenv (zmienne środowiskowe) lub @ (zmienne lokalne liczbowe).
$ set napis="Ala ma kota"
$ setenv HOME="/home/student"
$ @ wynik=10
Nazwa zmiennej może zawiać 20 znaków - dowolne litery, cyfry (cyfra nie może być pierwszym znakiem nazwy zmiennej) oraz znak podkreślenia.
Wartość umieszczoną w zmiennej wydobywamy umieszczając $ przed nazwą zmiennej
$ echo $napis
$ Ala ma kota
$ echo $HOME
$ /home/student
$ echo $wynik
$ 10
Zmienne kasujemy poleceniem unset oraz odpowiednio (zmienne środowiskowe) unsetenv
$ unset napis
$ unset wynik
$ unsetenv HOME
Należy pamiętać, że wartości umieszczone w zmiennych są ciągami znaków. Zmienna $wynik zawiera napis składający się ze znaków ’1’ i ’0’. Możliwe jest jednak wykonywanie prostych
operacji arytmetycznych.
Tablice deklarujemy w następujący sposób:
$ set dzien=(poniedzialek wtorek sroda czwartek piatek sobota niedziela)
$ echo $dzien
$ poniedzialek wtorek sroda czwartek piatek sobota niedziela
Elementy tablicy numerowane są liczbami naturalny (startując od 1), np.$dzien[3] odnosi się do
trzeciego elementu tablicy $dzien
$ echo $dzien[3] $dzien[5]
$ sroda piatek
$ echo $dzien[2-4]
$ wtorek sroda czwartek
$ set dzien[7]=sunday
$ echo $dzien
$ poniedzialek wtorek sroda czwartek piatek sobota sunday
Inny przykład:
$ set liczby=( `seq 1 10`)
$ echo $liczby
$ 1 2 3 4 5 6 7 8 9 10
Za pomocą wyrażenia $#zmienna możemy dowiedzieć się ile elementów
zawiera tablica zmiennych, np:
$ set dzien=(poniedzialek wtorek sroda czwartek piatek sobota niedziela)
$ echo $#dzien
$ 7
Operator $?zmienna zwraca wartość 1 jeśli zmienna jest zadeklarowana - 0 w przeciwnym
wypadku, np.:
$ echo $?dzien
$ 1
$ unset dzien
$ echo $?dzien
$ 0
Polecenie unset usuwa zmienną, stąd operacja $? w tym wypadku zwraca 0.
Zmienna $argv jest tablicą zawierającą parametry z jakimi został wywołany skrypt. Np. jeżeli uruchomimy skrypt:
$ nazwa_skryptu -n 10 ala
wówczas w zmiennej $argv umieszczone zostaną wszystkie parametry, odpowiednio:
$argv[1] zawiera ”-n”, argv[2] - ”10”, $argv[3] ”ala”.
W podobny sposób można używać zmiennych $1 $2 $3 itd., które również zawierają wartości kolejnych argumentów z wywołania skryptu jednak dodatkowo w zmiennej $0 zawarta jest nazwa wywoływanego skryptu.
Przykład - skrypt argv.sh:
#!/bin/tcsh set n = $#argv echo "Liczba argumentów = $n" echo "Nazwa skryptu: $0" set i=1 while ( $i <= $n ) echo "Argument $i = $argv[$i]" set i=`expr $i + 1` end exit 0
Uruchomienie skryptu:
$ ./argv.sh ala ma kota
Liczba argumentów = 3 Nazwa skryptu: ./argv.sh Argument 1 = ala Argument 2 = ma Argument 3 = kota
Argumenty wywołania skryptu zawarte są także w zmiennej $* a kolejne argumenty dostępne są w zmiennych $1, $2, $3, itd.
Powłoka tcsh pozwala na wykonywanie prostych operacji arytmetycznych za pomocą instrukcji @.
Przykład:
$ @ suma = 2 + 2
$ echo $suma
$ 4
$ @ liczba = $suma * 2
$ echo $liczba
$ 8
$ @ suma ++
$ echo $suma
$ 5
Operator ++ zwiększa liczbę zawartą w zmiennej o 1. W tcsh mamy do dyspozycji operatory występujące w języku C, ich lista
zawarta jest w tabeli 1:
operator | opis | przykład |
---|---|---|
Arytmetyczne | ||
dodawanie | @ a $liczba 1 | |
odejmowanie | @ a $liczba 2 | |
dzielenie | @ a $liczba 2 | |
mnożenie | @ a $liczba $liczba | |
reszta z dzielenia | @ a = $liczba % 2 | |
Relacje | ||
> | większy od | $liczba > 3 |
< | mniejszy od | $liczba < 3 |
== | równy | $liczba == $zmienna |
!= | różny od | $liczba != 2 |
Logiczne | ||
&& | AND | $liczba < 3 && $liczba < 7 |
|| | OR | $liczba == 1 || $liczba == 2 |
! | NOT | !( $liczba < 2 ) |
Operatory skracające zapis | ||
@ a = $a + 1 | @ a | |
@ a = $a - 1 | @ a | |
@ a = $a + $liczba | @ a $liczba | |
@ a = $a - $liczba | @ a $liczba | |
@ a = $a $liczba | @ a $liczba | |
@ a = $a $liczba | @ a $liczba |
Wartością wyrażeń zawierających operatory relacji jest 0 (fałsz) gdy wyrażenie nie jest prawdziwe lub 1 (prawda) gdy wyrażenie jest spełnione.
Proste operacje arytmetyczne można także wykonywać za pomocą instrukcji expr. Tak jak w każdym poleceniu argumenty instrukcji expr muszą byc oddzielone od siebie pustymi znakami.
Przykłady zastosowania:
$ set a=`expr 1 + 1`
$ set porownanie=`expr $a == 2`
$ set a=`expr $a + 5`
Obliczenia na liczbach zmiennopozycyjnych (rzeczywistych) nalezy wykonywac przy pomocy odpowiednich narzędzi (kalkulatorów).
Kalkulator dowolnej precyzji bc, przykład:
$ echo '1.5 * 3.1' | bc
$ set a=`echo '3.14*2' | bc`
$ set wynik=`echo ``scale=2; 1/$a'' | bc`
Zmienna scale w kalkulatorze bc określa liczbę miejsc po przecinku w wyświetlanym wyniku.
Składnia warunku:
if ( wyrażenie ) then
instrukcje
endif
Jeśli wyrażenie jest prawdziwe wówczas wykonywane są instrukcje zawarte po słowie then.
Przykład:
#!/bin/tcsh if( $#argv == 0) then echo "Nie podałeś żadnych argumentów " endif exit 0
Bardziej rozbudowane wyrażenie warunkowe:
if ( wyrażenie ) then
instrukcje 1
else
instrukcje 2
endif
Instrukcje zawarte w bloku rozpoczynającym się od else są wykonywane gdy wyrażenie nie jest spełnione. Np.:
#!/bin/tcsh if( $#argv == 0 ) then echo "Nie podałeś argumentów" else echo "Podałeś argumenty: $argv" endif exit 0
Za pomocą wyrażenia if możemy sprawdzać różne własności plików. Np.:
#!/bin/tcsh if( -e $argv[1] ) then echo "Plik o nazwie $argv[1] istnieje" else echo "Nie ma takiego pliku" endif
Wyrażenie -e nazwa_pliku powoduje sprawdzenie czy plik o danej nazwie istnieje.
W analogiczny sposób możemy sprawdzić inne własności plików. Najważniejsze z nich zawarte są w tabeli (5.5.3)
-e | plik istnieje |
---|---|
-f | plik istnieje i jest zwykłym plikiem |
-d | plik istnieje i jest katalogiem |
-r | użytkownik posiada prawo do czytania pliku |
-w | użytkownik posiada prawo do zmiany zawartości pliku |
-x | użytkownik posiada prawo do wykonywania pliku |
-o | użytkownik jest właścicielem pliku |
Przykład - skrypt o nazwie which.sh poszukuje podanego polecenia w jednym z katalogów zawartych w zmiennej $path i jeśli go znajdzie to wyświetla pełną ścieżkę do tego polecenia (czyli działa analogicznie do programu whereis):
#!/bin/tcsh if ( $#argv != 1 ) then echo "Skrypt określa położenie polecenia" echo "Skladnia: $0 polecenie" exit 1 endif foreach katalog ( $path ) set plik=${katalog}/$argv[1] if ( -f $plik && -x $plik ) then echo "Znalazlem: $plik" exit 0 endif end echo "Nie znalazlem" exit 2
Uruchomienie skryptu:
$ ./which.sh finger
Znalazlem: /usr/bin/finger
$ ./whitch.sh fing
Nie znalazlem
Jeszcze bardziej rozbudowane wyrażenie warunkowe:
if ( wyrażenie 1 ) then
instrukcje 1
else if ( wyrażenie 1 ) then
instrukcje 2
endif
Przykład:
#!/bin/tcsh if ( $#argv != 1 ) then echo "Podaj liczbe calkowita lub -h pomoc" exit 1 endif if ( $1 == "-h" ) then echo "Skrypt demonstruje uzycie zlozonego warunku if." echo "Dla danej liczby calkowitej dowiesz sie czy jest wieksza, mniejsza czy rowna 0." else if ( $1 > 0) then echo "Podales liczbe dodatnia." else if ( $i < 0 ) then echo "Podales liczbe ujemna" else if ($i == 0 ) then echo "Podales zero." else echo Podales argument $1 - nie wiem co z tym zrobic. endif exit 0
Składnia pętli while:
while ( wyrażenie )
instrukcje
end
Pętla jest wykonywana dopóki spełnione jest wyrażenie.
Przykład - skrypt o nazwie silnia.sh liczący silnię:
#!/bin/tcsh if ( $#argv != 1 ) then echo "Skrypt oblicza silnie z podanej liczby całkowitej" echo "Skladnia: $0 liczba" exit 1 endif set i=1 set silnia=1 while( $i < $argv[1]) @ i = $i + 1 @ silnia = $silnia * $i end echo "Silnia z liczby $argv[1] wynosi $silnia" exit 0
Uruchomienie skryptu:
$ ./silnia.sh 6
Silnia z liczby 6 wynosi 720
Pętla foreach wykonywana jest dla każdej wartości z zadanej lisy elementów.
foreach zmienna ( lista elementów )
instrukcje
end
W każdym kroku zmienna przybiera wartość kolejnego elementu z listy.
Przykład - skrypt home.sh dla każdego pliku (katalogu) zawartego w katalogu /home sprawdza uprawnienia do odczytu:
#!/bin/tcsh set pliki=`ls /home` foreach zmienna ( $pliki ) if ( -r /home/$zmienna ) then echo "Katalog /home/$zmienna - moge z niego czytac" endif end exit 0
Uruchomienie skryptu:
$ ./home.sh
Katalog /home/212598 - moge z niego czytac
Katalog /home/grochu - moge z niego czytac
Katalog /home/pk2-8 - moge z niego czytac
Instrukcja switch pozwala na wykonanie wybranych instrukcji w zależności od warości przyjmowanej przez pewną zmienną.
Działanie bardzo podobne do instrukcji if jednak często wygodniejsze w użyciu.
switch ( zmienna )
case wartość 1 :
instrukcje 1
breaksw
case wartość 2 :
instrukcje 2
breaksw
default:
instrukcje
endsw
Przykład:
#!/bin/tcsh switch ( $1 ) case "-h" : Ψecho "Opcja -h wyswietla pomoc. Sprobuj takze opcji -v." Ψbreaksw case "-v": Ψecho "Opcja -v wyswietla ten oto komunikat." Ψbreaksw default: Ψecho "Podales nieobslugiwana opcje $1" endsw
Instrukcja goto powoduje przeskoczenie do linii skryptu oznaczonego pewną etykietą pomijając wszystkie pośrednie instrukcje
goto etykieta
instrukcje 1
etykieta:
instrukcje 2
Wszystkie instrukcje 1 zostaną pominięte.
Przykład - skrypt goto.sh:
#!/bin/tcsh if ( $#argv == 0 ) then goto blad endif echo "Podales nastepujace argumenty wywolania sktyptu:" echo "$argv" echo "Milego dnia" exit 0 blad: echo "Nie podales argumentow - Nastapil skok do etykiety blad" exit 1
Uruchomienie skryptu:
$ ./goto.sh pewien argument
Podales nastepujace argumenty wywolania sktyptu:
pewien argument
Milego dnia
$ ./goto.sh
Nie podales argumentow - Nastapil skok do etykiety blad
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 $?.
Przykład - skrypt exit.sh:
#!/bin/tcsh if ( $#argv == 0 ) then echo "Podaj nazwe pliku jako argument" exit 1 endif if ( -f $argv[1] ) then echo "Ok, plik $argv[1] istnieje" exit 0 else echo "Blad, plik $argv[1] nie istnieje" exit 2 endif
Uruchomienie skryptu:
$ ./exit.sh
Podaj nazwe pliku jako argument
$ echo $?
1
$ ./exit.sh pewienplik
Blad, plik pewienplik nie istnieje
$ echo $?
2
$ ./exit.sh /bin/ls
Ok, plik /bin/ls istnieje
$ echo $?
0