Skrypty w systemie UNIX

Oryginalne materiały do ćwiczenia znajdują się pod adresem:
Skrypty w systemie UNIX

Wstęp

Z historycznego punktu widzenia, to własnie skrypty, pisane w powłokach (shell) systemu operacyjnego UNIX, są pierwowzorem dla programów wsadowych dla systemu operacyjnego DOS, a później również Windows. Sam system operacyjny był pisany w języku C, stąd często składnia poleceń, czy też same polecenia UNIX'a, są podobne do tego co można znaleźć w specyfikacji języka C. W przypadku skryptów pisanych w systemie UNIX obowiązują podobne zasady jak przy programach wsadowych pisanych w systemie Windows (DOS).

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, ściśle 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.

Przykład 1
Utwórz i wykonaj skrypt drukujący na ekranie tekst: Hello, world!


Wewnątrz skryptu można deklarować zmienne środowiskowe, np.:
TMP=/tmp/my_tmp
do których odwołujemy się podając ich nazwę poprzedzoną znakiem '$'.

Przykład 2
Utwórz i wykonaj skrypt następującej treści:
  #!/bin/sh
  TEKST="Hello, world!"
  echo $TEKST


Przekazywanie parametrów

Istnieją dwie proste metody przekazywania parametrów do skrypu:

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.

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

#!/bin/sh
echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9
shift 10
echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9

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

Zadania
  1. Czy wszystkie parametry wywołania zostały wydrukowane?
  2. Jak należy poprawić skrypt aby wydrukować wszystkie parametry?
  3. Zmodyfikuj skrypt tak aby wszystkie parametry były drukowane w jednej linii.
    W tym celu zapoznaj się z manualami do polecenia 'echo' oraz 'printf'.

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.

Przykład 4
Utwórz skrypt wczytujący dwa parametry.
#!/bin/sh
echo Podaj parametry a i b:
read a b

Zadania
  1. Uzupełnij skrypt tak, aby drukował wprowadzone wartości.
  2. Zmodyfikuj skrypt tak, aby komentarz i wprowadzane dane znajdowały się w jednej linii.


Instrukcja warunkowa 'if'

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

Przykład 5
Utworz skrypt porównujący dwie wartości i drukujący wynik.
#!/bin/sh
echo Podaj parametry a i b:
read a b
if [ "$a" = "$b" ]
  then
    echo rowne
  else
    echo nie rowne
fi

Zadania
  1. Zwróć uwagę na konstrukcję linii warunkowej oraz sposób zamykania polecenia.
  2. Zmodyfikuj skrypt tak, aby drukował wynik tylko wtedy, gdy oba parametry są od siebie różne.
  3. Zmodyfikuj skrypt tak, aby porównywał wartości numeryczne typu całkowitego.
  4. Przeczytaj w manualu do polecenia test jakie są jeszcze inne rodzaje warunków. Zwróć szczególną uwagę na warunki dotyczące plików.
  5. Napisz skrypt sprawdzający różne cechy plików.


Pętla iteracyjna 'for'

Pętla ta służy do wykonania pewnych instrukcji określoną ilość razy. Budowa pętli for jest nastepująca:

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

Przykład 6
  #!/bin/sh
  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).

Zadania
  1. Utwórz skrypt odliczający wstecz tak, aby otrzymać na ekranie wydruk postaci:
    6...5...4...3...2...1...KONIEC
  2. Utwórz skrypt drukujący długi listing zwykłych plików(!) w bierzącym katalogu.


Pętla 'while'

Pętla ta służy do wykonywania pewnych instrukcji, dopuki spełniony jest jakiś warunek. Budowa pętli while jest nastepująca:

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

Przykład 7
  #!/bin/sh
  while read a
  do
    if [ $a -eq 0 ]
      then
        exit
    fi
  done
W tym przypadku $a -eq 0 sprawdzane jest, czy zmienna a jest równa 0.

Instrukcja warunkowa 'case'

Jest to instrukcja wielokrotnego wyboru. Na podstawie wartości słowa wykonywane są odpowiednie instrukcje. Budowa instrukcji case jest następująca:

case <słowo> in
<wartość 1>)
   <instrukcje>
   ;;
<wartość 2> | <wartość 3>)
   <instrukcje>
   ;;
*)
   <instrukcje>
   ;;
esac

Przykład 8
  #!/bin/sh
  printf "To jest moj skrypt\n";
  printf "Prosze wpisac jakis znak\n";
  read tmp
  case $tmp in
    a | A ) echo 'Wpisano A' ;;
    b | B ) echo 'Wpisano B' ;;
    c | C ) echo 'Wpisano C' ;;
    d | D ) echo 'Wpisano D' ;;
    e | E ) echo 'Wpisano E' ;;
  esac
Proszę zwrócić uwagę, że skrypt ten wypisuje daną literę bez względu na wielkość znaku jaki został wpisany.
Zadania
  1. Utwórz skrypt, którego zadaniem będzie czytanie ciągu znaków z ekranu i drukowanie jakiejś informacji (np. jaki znak został wczytany) albo zakończenie działania w zależności od wczytanej wartości.

Valid XHTML 1.0 Transitional Valid CSS!