W poprzednich rozdziałach omówiliśmy sposoby korzystania z podstawowych poleceń shella. Jednak aby w pełni z niego korzystać, potrzebne są polecenie, które umożliwiają sprawowanie nadzoru nad tym co i kiedy zostanie wykonane. Nalezą do nich polecenia, za pomocą których, użytkownik może:

wybrać jedną z dwóch czynności  (if-then-else-fi)

wybrać jedna z wielu czynności    (case)

powtarzać czynności wiele razy    ( while, for, until )

 

Struktury tych poleceń składają się z dwóch głównych składników: testu i poleceń. Jeżeli wynik testu jest pozytywny, komendy zostają uruchomione. W programach powłoki shella używa się dwóch typów struktur kontrolnych: pętli i instrukcji warunkowych. Pętle służą do powtarzania komend, zaś instrukcje warunkowe – wykonują polecenia gdy spełnione sa określone warunki.

Bash Shell posiada trzy struktury pętli  while ,   forfor  in, oraz dwie instrukcje warunkowe  if case. Struktury  while  i  if  są dość ogólne. Są używane przede wszystkim do zdefiniowania warunków w jakich następują wykonywania powtórzeń i dokonywania decyzji przy użyciu rozmaitych testów. Natomiast instrukcje   case  i  for i ich użycie jest używane w dość szczególnych sytuacjach;  case jest rozwiniętą formą warunku  if   i jest często używana do budowy i obsługi  menu. Struktura  for jest zawężonym typem pętli. Przetwarza ona listę wartości przyporządkowując z każdym powtórzeniem pętli, nowa wartość określonej pętli. Możliwość korzystania z pętli i instrukcji warunkowych w połączeniu z poznanymi już poleceniami czyni z basha shella pełnowartościowy język programowania, który można wykorzystać do złożonych zadań przetwarzania informacji. Użytkownik bash shella będzie po zapoznaniu się i zrozumieniu tego rozdziału, zdolny do budowy skomplikowanych programów.


Używanie konstrukcji  if-then-fi

W jaki sposób  - przy pomocy jakich logicznych konstrukcji – człowiek podejmuje określone decyzje? Najprostszą logikę, leżącą u fundamentów każdej decyzji, można streścić w następujący sposób:  jeśli  (if) zachodzi jakiś warunek, to  (then) wykonuje działanie. Można to odnieść do każdej sytuacji, w tym do naszego codziennego życia. Na przykład, jeśli zadzwoni telefon to podniosę słuchawkę, jeśli zadzwoni dzwonek u drzwi to je otworze, jeśli będzie zimno to założę płaszcz itd. Przykłady można mnożyć w nieskończoność. Składnia tego typu logiki w krypcie pisanym bash-shell, wygląda tak:

 

if [ zachodzi określony warunek ]

then [ wykonaj jakieś działanie ]

fi

 

Struktura  if umieszcza warunek w poleceniu, jeśli polecenie zostanie pozytywnie zweryfikowane to wszystkie inne czynności w strukturze if zostaną wykonane. Mówimy w takim przypadku, że status polecenia-warunku jest równy 0, jeśli natomiast warunek zostanie zweryfikowany negatywnie – to znaczy, że nie jest prawdziwy, w takim wypadku status przybiera wartość fałszywą równą 1 i czynności zawarte w strukturze if nie zostaną wykonane.

Struktura  if rozpoczyna się od słowa kluczowego  if , po którym następuje polecenie Linuxa, którego status tzw. „status wyjściowy” ma zostać poddany weryfikacji. Polecenie-warunek jest zawsze uruchamiane.  Po nim umieszczone jest słowo kluczowe  then , po którym następuje dowolny zbiór poleceń Linuxa. Słowo  fi kończy całą strukturę. Często – pisząc skrypt – użytkownik musi wybrać pomiędzy dwoma alternatywami. Słowo  kluczowe  else pozwala strukturze  if na wybór pomiędzy dwiema alternatywami. Jeżeli weryfikacja polecenia-warunku jest prawdziwa, uruchomiony zostaje fragment programu umieszczony po słowie   then , w przeciwnym wypadku ten umieszczony po słowie  else. Struktura  polecenia if-then-else-fi pokazana jest poniżej :

 

if [ zachodzi okreslony warunek ]

then

wykonaj polecenie  x

else

wykonaj polecenie  y

fi

 

Wykonajmy prosty skrypt który zilustruje nam działanie struktury  if-then-else-fi. Skrypt proces1 w poniższym przykładzie uruchamia polecenie  ps z dwiema różnymi opcjami w celu wyświetlenia aktualnych procesów użytkownika egzekwującego ten skrypt albo procesy wszystkich użytkowników zalogowanych do systemu:

 

$  vi  proces1

#!/bin/bash

echo ”wcisnij u w celu wyswietlenia procesow  uzytkownika”

echo ”w przeciwnym wypadku zostana wyswietlone procesy wszystkich użytkowników’’

echo  -n „”Proszę wybrac opcje :   ”

read wybor


if [   „”$wybor=u  ]

....then

..........ps  -ul

....else

..........ps -al

fi

 

Uruchomienie skryptu ma postać:


wcisnij  u  w celu wyswietlenia procesow uzytkownika

w przeciwnym wypadku zostana wyswietlone procesy wszystkich uzytkownikow

Proszę wybrac opcje :   u

piotr         11736  11731                    0    13:45        pts/0            00:00:00    /bin/bash

piotr         11737  11732                    0    13:45        pts/1            00:00:00     /bin/bash

piotr         11738  11733                    0    13:45        pts/0            00:00:00     /bin/bash

 

 

Przejdźmy teraz do zaprezentowania ostatniej formy struktury if zwanej przez logików : „w przeciwnym razie jeśli”.  Struktura  elif pozwala na zagnieżdżenie operacji  if-then-else-if. Jej nazwa jest skrótem od  „else  if”. W strukturze  elif pierwsza operacja jest określona strukturą  if, za którą następują kolejne. Jeśli weryfikacja warunku-polecenia ze struktury  if jest nieprawdziwa, to kontrola zostaje przekazana strukturze elif i jej warunek jest testowany. Jeżeli warunek-polecenie  elif jest nieprawdziwy to wtedy, kontrola zostaje przekazana do następnej struktury  elif, jeżeli i ta jest nieprawdziwa wykonujemy polecenia zawarte w strukturze else. Składnia struktury elif znajduje się poniżej.


if [ warunek polecenie ]

....then

...komendy Linuxa

.....elif

...komendy Linuxa

....else

...komendy Linuxa

fi

 

 

W skrypcie   proces2  zaprezentowane zostały dwie metody wyświetlenia procesów użytkownika lub użytkowników.

 

echo  ” wyswietl procesy uzytkownika”

echo   ”wyswietl procesy wszystkich uzytkownikow”


echo  -n    „”Proszę wybrac opcej :   ”

read   wybor


if     [   ”$wybor”=u  ]

then

ps  -ul

elif  [   “$wybor”=l ]

then

ps -al

else

echo  “niewlasciwa opcja”

fi

echo  ”Do widzenia”

 

 

Polecenie test

Niezbędnym uzupełnieniem struktury kontrolnej   if-then-fi jest polecenie  test. Z jego pomocą można na przykład stwierdzić, czy dana nazwa jest nazwą pliku czy katalogu, czy jest to plik z prawami do czytania, pisania i wykonywania, czy dwa napisy lub dwie liczby są sobie równe lub nie czy jedna z nich jest większa albo mniejsza od drugiej. Polecenie to składa się z słowa  test wraz z wartościami, które maja być porównane, oddzielonymi operatorem określającym typ porównania. Porównywać można ciąg lub ciągi znaków, w tym wypadku występują następujące opcje dla tzw. porównania tekstowego

 

-z          sprawdza czy ciąg jest pusty

-n         sprawdza wartość ciągu

=          równy

!=         nierówny

Str        sprawdza czy ciąg jest zerowy

 

Polecenie test może także porównywać dwie liczby, w tym wypadku występują następujące opcje dla tzw. porównania liczbowego:

 

Porównanie liczbowe:             funkcje:

-gt                                      większy od

-lt                                        mniejszy od

-ge                                      większy lub równy

-le                                        mniejszy lub równy

-eq                                       równy

-ne                                       nierówny

 

Jak widać używanie polecenia test jest bardzo skomplikowane, dlatego pierwsza uwaga: aby sprawdzić czy dwa ciągi znaków są równe używa się znaku równości  = , aby porównać dwie liczby używa się opcji  -eq. Zauważmy, że te porównania są sprzeczne z naszym kulturowym doświadczeniem, ponieważ przez całe życie dwie liczby porównywaliśmy przy pomocy znaku równości  = .

Poszczególne opcje czy wyrażenia możemy łączyć przy pomocy operatorów logicznych AND (logiczna suma),  OR (logiczna alternatywa)  i NOT (logiczna negacja). Opcje operacji logicznych są następujące:

 

 

-a   logiczna suma ( i )

-o   logiczna alternatywa (lub)

!     logiczna negacja  ( nie )

 

Polecenie test służy także do przeprowadzenia testów na plikach:

 

Opcja:                           funkcja:

-f                          plik istnieje i jest zwykłym plikiem

-s                         plik nie jest pusty

-r                          plik jest możliwy do odczytu

-w                         plik może być modyfikowany

-x                         plik jest skryptem uruchamialnym

-d                         plik jest katalogiem

-h                         plik jest łączem symbolicznym

-c                         plik jest urządzeniem

-b                         plik jest plikiem blokowym

 

Polecenie test , podobnie do innych poleceń shella, zwraca wartość  0 jeżeli jest prawdą i 1 jeżeli jest fałszem w zmiennej  $? . Podamy teraz kilka przykładów w których użyjemy polecenia  test. Chcemy się upewnić czy dwa napisy:  „ala”  i  „kola” są równe .Przypominamy ,że zmienna specjalna  $? przechowuje status wyjściowy ostatnio użytej komendy Linuxa:

 

$  test  „ala”  =  „kola”

$  echo $?

1


$  num=1

$  test  $num  -eq  3

$  echo  $?

1

 

Polecenie test można zastąpić stosując kwadratowe nawiasy [   ]. Dlatego powyższe ćwiczenia można zapisać.

 

$   [  „ala”  =  „kola”  ] .. równoważne       $  test  „ala”  = „kola”

$   [  $num  -eq  3  ] ......równoważne       test  $num –eq  3

 

Po pierwszym  [ musimy wystukać  spacje, tak samo przed   ] musimy zrobić to samo.

 

[    $num  -eq  3   ]

..↑                         ↑

 

 

spacja           spacja

 

Jeżeli pomiędzy [ i $num nie będzie spacji komenda nie będzie działać: omijanie tej zasady jest źródłem licznych błędów. Jak widzimy polecenie  test może przybierać różne formy.


1.     test

2.     [     ]

 

Innymi słowy  polecenie [    ]  jest aliasem polecenia test, stąd trzeba po nim wpisywać spacje. Przypominamy, że po każdym poleceniu w linii poleceń lub w skrypcie musimy wpisać spacje, jeżeli zamiast np.

 

$ grep plik1

 

napisalibyśmy grepplik1, to polecenie nie zostałoby wykonane, tak samo jeżeli zamiast:

 

[  plik1 ] wpisalibyśmy  [plik1] to polecenie nie zostałoby wykonane.

Kładziemy na to nacisk ponieważ nawiasy kwadratowe i ich użycie często nie są uważane przez użytkowników jako polecenie!

 

Wykonajmy kilka przykładów z poleceniem  [   ] i jego równoważnikiem poleceniem  test. Aby sprawdzić czy zalogowany właśnie użytkownik jest rootem (administratorem systemu), należy wydąć polecenie:

 

$  [   ’’$LOGNAME’’  =  root  ]

$ echo  $?

0

 

Oznacza to że root jest zalogowany i że to właśnie wykonuje polecenie. Gdyby tak nie było, zwrócona zostałaby wartość  1 lub większa od zera, co możemy zobaczyć w poniższym przykładzie:

 

 

$  [   ’’$LOGNAME’’  =  ‘’piotr”  ]

$ echo  $?

1

$

 

 

Polecenia logiczne  :   &&   i   ||

 

Polecenia logiczne wykonują operacje logiczne  na dwóch poleceniach logicznych. W przypadku logicznej koniunkcji wyrażonej tutaj symbolem  && jeśli oba polecenia  umieszczone po obu stronach operatora są prawdziwe, to całość jest prawdziwa.

W przypadku logicznej alternatywy wyrażonej tutaj symbolem  || , jeśli jedno z poleceń umieszczonych po obu stronach operatora jest prawdziwe, to całość jest prawdziwa.

polecenie  &&   polecenie

polecenie   ||    polecenie

 

 

 

Programowanie Rozdział 9.7 Darmowy kurs Linux