Przekazywanie parametrów do skryptu
Utwórzmy plik o nazwie katalog1, który będzie zawierał tylko jedno polecenie :
# vi katalog1
Następnie nadajmy wszystkim użytkownikom prawo do jego wykonywania:
# chmod a+x katalog1
W tym momencie skrypt katalog1 możemy wyegzekwować, wiemy jednak, że lista plików i podkatalogów wyświetlona na ekranie dotyczyłaby tylko katalogu bieżącego. Co możemy zrobić by otrzymać listę plików z innych katalogów bez każdorazowego poprawiania skryptu katalog1 ?
Aby zautomatyzować (przynajmniej częściowo) wyświetlanie plików w różnych katalogach, zastosujemy mechanizm przekazywania parametrów do skryptu. Jak pamiętamy polecenie w Linuksie składa się z samego polecenia np. ls , opcji np. –l i argumentów np. /usr. Zarówno opcje jak argumenty możemy nazwać parametrami. Nazwa skryptu jest też poleceniem, któremu możemy przekazać parametry, z tym że parametry przekazywane do skryptu przypisywane są zmiennym, które oznaczamy jako $1, S2……S9. $1 odpowiada pierwszemu argumentowi polecenia, $2 drugiemu itd. Co to w praktyce oznacza ?
Przypuśćmy, że chcemy wyświetlić na ekranie – egzekwując skrypt katalog1 – zawartość katalogu /tmp, w tym celu wykonamy następujące polecenie:
$ katalog1 /tmp
Jest to wartość, którą przyjmuje zmienna $1 (pierwszy argument polecenia katalog1), z czego wynika, że nasz skrypt musimy zmienić w następujący sposób:
$1 przybiera zawsze wartość pierwszego argumentu polecenia w tym wypadku /tmp, jeżeli chcielibyśmy obejrzeć zawartość katalogu /usr to musimy wykonać polecenie:
# ./katalog /usr
$1 przybierze w tym wypadku wartość /usr
Dodajmy, że istnieje także zmienna $0 zawiera ona nazwę skryptu (polecenia). Wiemy, że możemy skryptowi przekazać 9 parametrów od $1 do $9. Przećwiczmy problem parametrów praktycznie. W tym celu utworzymy plik o nazwie skrypt2.
$ vi skrypt2
Następnie – po nadaniu odpowiednich praw skryptowi (jeżeli użytkownik tych praw nie posiada) wyegzekwujmy skrypt1 w następujący sposób:
....$1 $2 $3
$ ./skrypt1 89 34 21
Na ekranie powinny pojawić się napisy:
Zmienne oznaczone znakiem $ mogą w linii poleceń egzekucji skryptu przybierać także wartości następujące:
$* → reprezentuje wszystkie zmienne, niezależnie od ich liczby
$# → pokazuje liczbę podanych zmiennych
$@ → argumenty linii poleceń są „cytowane” pojedynczo
Bardzo ważna jest różnica między wyrażeniami $* (wszystkie zmienne) i $# (liczba zmiennych). Pierwsza wartość ($*) odnosi się do wszystkiego, co jest w wierszu poleceń, od $1 do nieskończoności (choć tak naprawdę w każdej powłoce jest jakiś limit zmiennych). Druga wartość ($#) nie odnosi się do samych zmiennych, ale zwraca ich liczbę. Aby pokazać tę różnicę, rozważmy poniższe skrypty. Utwórzmy skrypt pod nazwą skrypt3 który zawierał będzie tylko:
$ vi skrypt3
$ ./skrypt2 x y z q
x y z q
zmieńmy teraz skrytp 3 i porównajmy wyniki obu wersji:
$ ./skrypt3 x y z q
4
Jak więc widzimy zmienna S* odnosi się do wszystkich argumentów z linii poleceń natomiast zmienna $# liczy te argumenty. Jaka jest w takim razie różnica pomiędzy zmienną $* a zmienną $@ ? Obie robią to samo jednak zmienna $@ pozwala na osobne użycie każdego z nich. Różnica pomiędzy tymi zmiennymi nie jest zbyt widoczna, dopóki nie użyjemy ich do argumentów używających strukturę kontrolną pętli for-in co będzie wyjaśnione w dalszej części rozdziału.
W zarządzaniu zmiennymi $ definiowanymi przez system możemy użyć polecenia shift. Polecenie to bierze wszystkie zmienne począwszy od $1 i zmniejsza ich liczbę o jeden. Zmienna $0 nigdy się nie zmienia, ale kiedy używamy polecenia shift po raz pierwszy to $2 staje się $1, $3 staje się $2 itd. Proces ten powtarza się przy każdorazowym użyciu polecenia shift. Utwórzmy skrypt4:
$ vi skrypt4
Dokonamy teraz egzekucji skrypt3 z następującymi argumentami:
$ skrypt3 raz dwa trzy cztery
Polecenie shift nie wie, ani czy zmienne istnieją, ani ile ich jest. W przypadku dużej liczby zmiennych nie stanowi to problemu, ale w przypadku małej liczby zmiennych można nieświadomie przesuwać nieistniejące zmienne, co może powodować wyświetlanie pustych wierszy, a czasami nawet komunikatów o błędach. Jeśli w powyższym przykładzie podamy w wierszu poleceń tylko jedna zmienną, wygenerowany zostanie następujący komunikat o błędzie:
shift : shift skrtpt3 must be <= $#
Linux dostarcza nam także inne zmienne zdefiniowane w systemie, które ułatwiają programowanie w bashu:
? → zmienna ta zawiera kod zwrotu ostatniego polecenia wykonanego przez skrypt
$ → zmienna ta zawiera numer procesu – PID
Programowanie Rozdział 9.3 Darmowy kurs Linux