8. Skrypty


1. Wstęp


Jednym z podstawowych narzędzi ułatwiających pracę w systemie UNIX są skrypty. Skrypty tworzy się używając języka właściwego dla danej powłoki systemowej (np. sh, csh) albo specjalnego języka skryptowego (np. perl, tcl). Składnia języków skryptowych jest bardzo podobna do składni języków wysokiego poziomu, przy czym podstawowe polenia w skrypcie mają postać zwykłych poleceń wydawanych w danej powłoce systemowej. Skrypty zapisuje się w plikach według prostych, ścisle określonych zasad. Plik zawierający skrypt dedykowany dla konkretnego języka powinien zaczynać się deklaracją odpowiedniego interpretera składni, np.:

#!/bin/sh
#!/bin/csh
#!/bin/perl


Pominięcie deklaracji interpretera spowoduje próbę wykonania skryptu przez bieżącą powłokę, co może zakończyć się niepowodzeniem, ze względu na różnice składni obsługiwanej przez różne interpretery. Ponadto podczas tworzenia skryptu należy zwrócić uwagę na prawa dostępu dla pliku zawierajacego treść skryptu (prawo execute). Treścią laboratorium będzie tworzenie skryptów dedykowanych dla powłoki sh (Bourn shell). Podstawy składni języka skryptów dla powłoki sh opisane są np. w manual'ach (man sh) i answerbook'u.

Zadanie 1.1 Utwórz i wykonaj skrypt drukujący na ekranie tekst: Hello, world!
                  - należy otworzyć plik w dowolnym edytorze
                  - należy wpisać do niego następującą treść:
                                           echo "Hello, world!"
                  - należy plik zamknąć i ustawić odpowiednie prawa:
                                           chmod u+x <nazwa pliku>
                  - należy wykonać skrypt poleceniem:
                                           ./<nazwa pliku>

Wewnątrz skryptu można deklarować zmienne środowiskowe, np.:

TMP=/tmp/my_tmp ,

do których odwołujemy się opdając ich nazwę poprzedzoną znakiem '$'.

Zadanie 1.2 Utwórz i wykonaj skrypt następującej treści:

                                           TEKST="Hello, world!"
                                           echo $TEKST

2. Przekazywanie parametrów


Istnieją dwie proste metody przekazywania parametrów do skrypu:
   - poprzez parametry wywołania:
                    % <skrypt> <par1> ... <par#> ,
   - w trybie interakcyjnym.

Prametry przekazywane do skryptu w linii wywołania reprezentowane są poprzez cyfry od '0' do '9'.  Parametr oznaczony cyfrą '0' oznacza nazwę skryptu. Jeżeli liczba parametrów przekracza 10, to w celu odwołania się do tych parametrów stosuje się polecenie 'shift' podając jako parametr zakres przesunięcia. Operacja ta jest nieodwracalna.

Zadanie 2.1 Utwórz skrypt drukujący parametry wywołania, których powinno być więcej niż 10.

          ...
          echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9
          shift 10
          echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9


          % ./<nazwa skryptu> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Czy wszystkie parametry wywołania zostały wydrukowane? Jeżeli nie to jak należy poprawić skrypt aby wydrukować wszystkie parametry? Zmodyfikuj skrypt tak aby wszystkie parametry były drukowane w jednej linii.

Aby przekazać do skryptu parametry w trybie interakcyjnym należy użyć polecenia 'read' podając jako parametr nazwę zmiennej, której chcemy nadać wartość. W jednej linii można wczytać więcej niż jeden parametr. Wczytanie parametru można poprzedzić komentarzem.

Zadanie 2.2 Utwórz skrypt wczytujący dwa parametry.

          echo Podaj parametry a i b:
          read a b

- Uzupełnij skrypt tak, aby drukował wprowadzone wartości.
- Zmodyfikuj skrypt tak, aby komentarz i wprowadzane dane znajdowały się w jednej linii. W tym celu zapoznaj się z manualami do polecenia 'echo ' oraz 'printf'.

3. Instrukcja warunkowa 'if'

Konstrukcja polecenia 'if' jest zbliżona do tych znanych z języków wysokiego poziomu.

Zadanie 3.1 Wykorzystując skrypt z poprzedniego zadania utworz skrypt porównujący dwie wartości i drukujący wynik.

          if [ "$a" = "$b" ]
           then
            echo rowne
           else
            echo nie rowne
          fi


- Zwróć uwagę na konstrukcję linii warunkowej oraz sposób zamykania polecenia.
- Zmodyfikuj skrypt tak, aby cała instrukcja warunkowa znajdowała się w jednej linii.
- Zmodyfikuj skrypt tak, aby drukował wynik tylko wtedy, gdy oba parametry są od siebie różne.
- Zmodyfikuj skrypt tak, aby porównywał wartości numeryczne typu 'integer'.

Zadanie 3.2 Przeczytaj w manualu do powłoki albo do polecenia 'if' jakie są jeszcze inne rodzaje warunków. Zwróć szczególną uwagę na warunki dotyczące plików i napisz skrypt sprawdzający różne cechy plików.

UWAGA: Począwszy od tego miejsca w celu sprawdzenia sposobu użycia poszczególnych poleceń można odwoływać się do treści skryptów systemowych znajdujących się w katalogu '/etc/init.d'.

4. Pętla 'for'

Budowa pętli for jest nastepująca:

for <parametr> in <lista słów> do <lista poleceń> done

Przykład:

          for i in 1 2 3 4 5 6
          do
           echo $i
           sleep 1
          done


W wyniku wykonania powyższej instrukcji na ekranie będą drukowane kolejne liczby od 1 do 6, każda w osobnej linii, w odstępach jedno sekundowych (polecenie sleep).

Zadanie 4.1 Utwórz skrypt odliczający wstecz tak, aby otrzymać na ekranie wydruk postaci:

6...5...4...3...2...1...KONIEC

Zadanie 4.2 Utwórz skrypt drukujący długi listing zwykłych plików(!) w bierzącym katalogu.

5. Pętla 'while'

Budowa pętli while jest nastepująca:

while <lista warunków> do <lista poleceń> done

Przykład:

          while read a
          do
           if [ $a -eq 0 ]
           then
            exit
           fi
          done

6. Instrukcja warunkowa 'case'

Budowa instrukcji case jest następująca:

case <słowo> in
<przykład>)
   <lista poleceń>
   ;;
<przykład>|<przykład>)
   <lista poleceń>
   ;;
*)
   <lista poleceń>
   ;;
esac

Zadanie 6.1 Utwórz skrypt, którego zadaniem będzie czytanie ciągu znaków z ekranu i drukowanie jakiejś informacji albo zakończenie działania w zależności od wczytanej wartości.