SKRYPTY W JĘZYKU INTERPRETERA POLECEŃ

Język poleceń bash'a może być uważany za skryptowy język programowania. Oznacza to, że polecenia mogą nie tylko być używane w linii poleceń, ale również mogą być umieszczane (w większej liczbie) w plikach (nazywanych skryptami), które następnie są uruchamiane jako całość. W związku z tym skrypty muszą mieć nadane zarówno prawo do odczytu (r), jak i do wykonywania (x) dla tego, kto je będzie uruchamiał.

Języki skryptowe (interpretowane) różnią się od języków kompilowanych tym, że programy w nich napisane nie podlegają kompilacji (tłumaczeniu w całości i dołączaniu podprogramów bibliotecznych) na język wewnętrzny komputera, tylko pojedyncze instrukcje podlegają tłumaczeniu "na bieżąco" (są interpretowane przez program interpretera poleceń - w tym przypadku przez bash'a). Niektóre języki programowania (na przykład Basic) mogą być używane zarówno jako języki interpretowane, jak i kompilowane. Programy skompilowane są wykonywane dużo szybciej, niż programy interpretowane, ale wprowadzanie w nich zmian wymaga później ponownej kompilacji całości.

W systemach uniksowych zazwyczaj jest dostępnych co najmniej kilka różnych interpreterów, z których jeden (zwykle bash) uważany jest za interpreter domyślny. W przypadku, gdy skrypt przeznaczony jest do wykonywania pod bieżącym interpreterem (tym, z którym aktualnie współpracujemy w oknie tekstowym), nie ma potrzeby umieszczania na jego początku żadnej dodatkowej informacji, natomiast jeśli chcemy wymusić interpretację skryptu przez pewien wybrany interpreter, umieszczamy na jego początku linię sterującą o postaci:

 #!........ (bezwzględna ścieżka dostępu do programu interpretera)

Przykłady:

	#!/bin/bash
	#!/bin/csh
Innym sposobem jest podanie polecenia o postaci:
nazwa_interpretera nazwa_skryptu

Przykład:
	
	sh moj_skrypt
Bash jest pełnowartościowym skryptowym językiem programowania - oznacza to, że umożliwia nie tylko tworzenie skryptów o prostej, liniowej strukturze (to jest takich, w których polecenia wykonywane są po kolei, od pierwszego do ostatniego), ale również dysponuje instrukcjami sterującymi (złożonymi), które mogą wpływać na kolejność wykonywania pozostałych instrukcji. Bash udostępnia instrukcję warunkową (if), instrukcję wyboru (case), instrukcje iteracji (pętli) nieograniczonej (while i until) oraz dwie postacie instrukcji iteracji ograniczonej (for), jak również kilka innych, specyficznych dla bash'a instrukcji złożonych. Instrukcje sterujące na ogół są stosowane w skryptach, ale mogą również być używane bezpośrednio w linii poleceń.
Starsza wersja "for" przechodzi po obiektach, np. plikach o danym rozszerzeniu:
for i in *.rozszerzenie;
do
    echo "$i";
done
Nowsza ma postać podobną do klasycznej pętli w C, np.:
for (( i=1; $i <= 5; i++ ));
do
    echo $i;
done
Operatory logiczne dla wyrażeń
wyrażenia o wartości logicznej z liczbami całkowitymi: wyrażenia o wartości logicznej z napisami: wyrażenia o wartości logicznej z plikami i katalogami: Instrukcja warunkowa if
if [[ warunek1 ]]
then
 # instrukcje wykonywane, jeżeli warunek1 jest spełniony
elif [[ warunek2 ]]
then
 # instrukcje wykonywane, jeżeli poprzedni warunek nie został spełniony natomiast warunek2 jest spełniony
# ...
else
 # instrukcje wykonywane, jeżeli żadne z wcześniejszych wyrażeń nie został spełniony
fi
ZADANIA

Zad. 1
Utworzyć plik o dowolnej nazwie i następującej zawartości:
 clear
 echo "To jest pierwszy napis"
 echo "A to jest drugi napis"
 exit 0
a następnie uruchomić go.

Zad. 2
Napisać i uruchomić skrypt wczytujący i wyświetlający łańcuch (napis):
 clear
 echo -n "Napisz cos: "
 read x
 echo "Otrzymalem napis: $x"
 exit 0


Skrypty (podobnie, jak inne programy uruchamiane w trybie tekstowym) mogą w chwili swojego uruchomienia otrzymać pewną liczbę argumentów wywołania podanych w linii poleceń:
 nazwa_programu argument_1 argument_2 ... argument_n
Podawanie argumentów jest najbardziej podstawowym sposobem podawania danych dla programu (zwykle są to dane o charakterze "sterującym", a właściwy strumień danych jest podawany przez wejście standardowe). Programy mogą mieć stałą lub zmienną liczbę argumentów. UWAGA: sama nazwa programu też jest uważana za argument (o numerze 0).

Zad. 3
Napisać i uruchomić skrypt, który: a) otrzymuje trzy argumenty wywołania i kolejno je wyświetla:
 echo $1 $2 $3
b) otrzymuje dowolną liczbę argumentów wywołania i wyświetla je wszystkie:
 echo $*
c) otrzymuje dowolną liczbę argumentów wywołania i wyświetla, ile ich otrzymał:
 echo $#

Zad. 4
Utworzyć dwa proste skrypty o nazwach odpowiednio Pierwszy i Drugi, które robią cokolwiek (np. wyświetlają coś), a następnie skrypt, który po kolei wywołuje je w swojej treści (jako podprogramy):
 ...
 echo Uruchamiam pierwszy skrypt
 ./Pierwszy
 sleep 3
 echo Uruchamiam drugi skrypt
 ./Drugi
 sleep 3
 echo Koncze dzialanie
 exit 0



W przypadku uruchamiania skryptów tak, jak robiliśmy to do tej pory (podanie w linii poleceń nazwy skryptu i ewentualnych argumentów wywołania), tworzony jest nowy proces (potomny względem bieżącego interpretera, w nowej podpowłoce), który inicjuje wykonywanie skryptu (dlatego umieszczaliśmy exit 0, które powodowało powrót do powłoki rodzicielskiej). Jest też jednak możliwe uruchomienie skryptu w ramach procesu bieżącego interpretera.

Zad. 5
Utworzyć skrypt, który tworzy nową zmienną środowiska i nadaje jej wartość (uwaga: nie umieszczać exit 0 na końcu tego skryptu). Uruchomić skrypt: a) w podpowłoce (czyli tak, jak do tej pory); b) w bieżącej powłoce (pisząc . skrypt lub source skrypt). Za każdym razem po wykonaniu skryptu sprawdzać, czy utworzona zmienna środowiska nadal istnieje, a jeżeli tak, to usunąć ją. UWAGA: w poleceniu . skrypt spacja po kropce jest konieczna.

Zad. 6
Przeczytać opisy poleceń złożonych (sterujących) bash'a. Wypróbować możliwość podawania ich bezpośrednio w linii poleceń, np.
 declare -i a b
 a= ...... #jakaś liczba
 b= ...... #jakaś inna liczba
 if [ $a -gt $b ]; then echo "Wieksza: $a"; else echo "Wieksza: $b";fi
Przeprowadzić analogiczną próbę naciskając Enter zamiast podawania kolejnych średników, zaobserwować inny znak zgłoszenia (secondary prompt).

Zad. 7
Utworzyć skrypt, który wczytuje dwie liczby całkowite, a następnie wyświetla ich sumę. Zmodyfikować skrypt tak, żeby zamiast wczytywać dane pobierał je z argumentów wywołania (np. suma 5 8).

Zad. 8
Utworzyć skrypt, który w bieżącym katalogu tworzy podkatalog Teksty, przenosi do niego z bieżącego katalogu wszystkie pliki, których nazwy kończą się na .txt i ustanawia prawa dostępu 600 do tych plików i 700 do podkatalogu Teksty.

Zad. 9
Utworzyć skrypt, który wypisze listę plików z bieżącego katalogu posortowaną malejąco według numerów i-węzłów, i-węzeł znajduje się w pierwszej kolumnie po zastosowaniu polecenia ls -i (wskazówka: można użyć polecenia "sort").

Zad. 10
Utworzyć skrypt o dwóch argumentach wywołania (pierwszym liczbowym, a drugim napisowym), który $1 razy wyświetli napis $2 (wskazówka: użyć nowszej formy polecenia "for").

Zad. 11
Utworzyć skrypt, który pobierze od użytkownika 5 liczb, wstawi je to tablicy, pobierze kolejną liczbę "mnożnik", a następnie pomnoży każdą komórkę tablicy przez "mnożnik" i wyświetli w konsoli uaktualnioną tablicę.

Zad. 12
Napisz skrypt, który wyświetli wszystkie pobrane argumenty w odwrotnej kolejności, np. argumenty 1 2 3, powinny zostać wyświetlone jako 3 2 1. Wykorzystaj tablicę.

Zad. 13
Utworzyć skrypt, który wyświetli nazwę i rozmiar tego pliku w bieżącym katalogu, który ma największy rozmiar (wskazówka: użyć polecenia "du").

Zad. 14
Napisz skrypt, który wyświetli informacje odnośnie tego jaka jest ścieżka do pliku terminala osoby, której login zostanie pobrany jako argument.