background image

Uniwersytet w Białymstoku

Wydział Matematyki i Informatyki

Instytut Informatyki

Materiały bazowe do zajęć z przedmiotu:

Systemy operacyjne

Laboratorium nr 08

Temat:

Zmienne tablicowe, pętle for, while i until

mgr Adam Bonda

Białystok 2008

background image

Cel laboratorium:  Zapoznanie si

ę

 z u

Ŝ

yciem p

ę

tli  

for

,  

while

,  

until

  w poł

ą

czeniu z

rozszerzon

ą

  arytmetyk

ą

  parametrów   ich   wywołania   i   zastosowaniem   zmiennych

tablicowych.

Podwójne   nawiasy  

((   wyrażenie   ))

  oraz   podwójne   nawiasy   kwadratowe

[[ wyrażenie ]]

Podwójne nawiasy  pozwalaj

ą

 na bezpo

ś

rednie wprowadzanie bardziej zaawansowanych

formuł   matematycznych   na   poziomie   porówna

ń

  komend   strukturalnych   (

if-then

)   w

odró

Ŝ

nieniu   od   polecenie   test,   które   oferowało   u

Ŝ

ycie   tylko   prostych   operacji

arytmetycznych.
Składnia    

wyrażenie  

mo

Ŝ

e   by

ć

  zarówno   matematycznym   jak   i   porównawczym

wyra

Ŝ

eniem.

$ cat skrypt.sh
#!/bin/bash
var_1=5
if (( $var_1 ** 2 20 ))
then
   (( var_2 = $var_1 ** 2 ))
   echo "Kwadratem liczby $var_1 jest $var_2"
fi
$ ./skrypt.sh
Kwadratem liczby 5 jest 25

Dozwolone   jest   stosowanie   nast

ę

puj

ą

cych   operatorów   w   wi

ę

kszo

ś

ci   znanych   ju

Ŝ

  z

poprzednich zaj

ęć

i++, i--, ++i, --i, !, ~, **, <<, >>, &, |, &&, ||

.

Podwójne nawiasy kwadratowe pozwalaj

ą

 na u

Ŝ

ycie zaawansowanych porówna

ń

 ci

ą

gów

znaków.   Porównywanie   stringów   zapisanych,   jako   wyra

Ŝ

enia   otoczone   tymi   symbolami

odbywa   si

ę

  podobnie   jak   w   przypadku   polecenia   test.   Symbol   podwójnego   nawiasu

kwadratowego zapewnia jednak skorzystanie z dodatkowej opcji, której polecenie test nie
posiada, porównywania wzorców. W porównywanym wzorcu mo

Ŝ

liwe jest zdefiniowanie

wyra

Ŝ

enia regularnego, które porównywane jest z ci

ą

giem znakowym.

$ cat skrypt.sh
#!/bin/bash
if [[ $SHELL == xt* ]]
then
   echo "Używasz terminala $SHELL"
else
   echo "Hmm, a mówiłem, żeby nie instalować nowych \"wynalazków\""
   echo "ale z drugiej strony, może ten terminal zjada mniej zasobów?"
fi

Zmienne tablicowe

Powłoka  

bash

  umo

Ŝ

liwia   korzystanie   z   jednowymiarowych   tablic.   Nazywane   s

ą

  one

zmiennymi tablicowymi, poniewa

Ŝ

 mog

ą

 przechowywa

ć

 wi

ę

cej ni

Ŝ

 jedn

ą

 warto

ść

. Ka

Ŝ

da

warto

ść

  indeksowana   jest  liczb

ą

  całkowit

ą

,   a   indeks  elementu   tablicy  umieszcza   si

ę

  w

nawiasach kwadratowych, jak podano w przykładzie ni

Ŝ

ej:

TABLICA1[0]="wartość zerowego"
TABLICA1[1]=drugi
TABLICA1[2]=3
TABLICA1[4]=iv

background image

Mo

Ŝ

liwa jest inicjacja wielu elementów tablicy naraz:

TABLICA2=( "wartość zerowego" pierwszego [9]=numer iv )

Elementy tablicy rozdziela si

ę

 spacjami i wylicza poczynaj

ą

c od elementu o indeksie 

0

. Jak

wida

ć

 powy

Ŝ

szym przykładzie mo

Ŝ

na tworzy

ć

 elementy o konkretnym indeksie, poprzez

zadeklarowanie jego numeru w nawiasach klamrowych.

Odwołanie   si

ę

  do   warto

ś

ci   elementu   zmiennej   tablicowej   mo

Ŝ

liwe   jest   poprzez

zastosowanie wyra

Ŝ

enia:

${nazwa_zmiennej_tablicowej[indeks]}

$ echo ${TABLICA2[0]}
wartość zerowego

Wy

ś

wietlony został element tablicy o indeksie zero

$ echo ${TABLICA2[3]}

Element o indeksie 3 nie istnieje, zwrócona wi

ę

c została warto

ść

 pusta.

$ echo ${TABLICA2[9]}
numer

Element o indeksie 9, przechowuje warto

ść

 „numer”.

$ echo ${TABLICA2[10]}
iv

Je

ś

li w tablicy zadeklarowano warto

ść

 nie b

ę

d

ą

c

ą

 kontynuacj

ą

 poprzednich indeksów to

tworzone   dalej   elementy   (bez   podania   numeru)   indeksowane     s

ą

  kolejnymi   liczbami

całkowitymi.   W   tym   przypadku   nie   podanie   indeksu   warto

ś

ci   „iv”   spowodowało

automatyczne przydzielenie jej warto

ś

ci (

10

) wy

Ŝ

szej o jeden ni

Ŝ

 indeks j

ą

 poprzedzaj

ą

cy

(

9

).

U

Ŝ

ycie zmiennych specjalnych, jako indeksów jest równie

Ŝ

 dozwolone np.: 

${zmienna[*]}, "${zmienna[*]}", ${zmienna[@]}

.

$ echo ${TABLICA2[*]}
wartość zerowego pierwszego numer iv

Wy

ś

wietlone zostały wszystkie elementy tablicy

$ echo "${TABLICA2[*]}"
wartość zerowego|pierwszego|numer|iv

Wy

ś

wietlone   zostały   wszystkie   elementy   tablicy,   a   podwójne   cytowania   spowodowało

u

Ŝ

ycie separatora zdefiniowanego zmienn

ą

 systemow

ą

 

IFS 

(ang. internal field separator).

Domy

ś

lnie powłoka 

bash

, jako separatorów u

Ŝ

ywa: spacji, tabulatora, znaku nowej linii.

Podobnie   jak   w   przypadku   zmiennych,   zmienne   tablicowe   i   ich   elementy   usuwa   si

ę

poleceniem 

unset

.

unset TABLICA2[9]
$ echo ${TABLICA2[*]}
wartość zerowego pierwszego iv
Usunięto element o indeksie 9.
$ echo ${TABLICA2[9]}

$ echo ${TABLICA2[10]}
iv

background image

Warto

ść

 elementu indeksowanego liczb

ą

 

9

  jest pusta. Nie nast

ą

piła jednak reindeksacja

elementów   i   nast

ę

pny,   w   stosunku   do   usuni

ę

tego   elementu,   posiada   w   dalszym   ci

ą

gu

indeks o numerze 

10

.

unset TABLICA2
$ echo ${TABLICA2[*]}

Usuni

ę

ta została zmienna tablicowa i wszystkie jej elementy.

Instrukcja wyboru 

case

Działanie   komendy  

case

  jest   podobne   do   konstrukcji   warunkowej  

if-then

.   Jak   sama

nazwa wskazuje dotyczy ona wyborów, a wi

ę

c okre

ś

lenia, który fragment kodu zostanie

wykonany   na   zasadzie   sprawdzania   przynale

Ŝ

no

ś

ci   testowanej   warto

ś

ci   do   z   góry

okre

ś

lonego zbioru.

Ogólna posta

ć

 tej konstrukcji przedstawia si

ę

 nast

ę

puj

ą

co:

case zmienna in
   szablon1 | szablon2komenda1;;
   szablon3)
      komenda2
      komenda3
      komenda3
      ;;
   *) domyślne_komendy;;
esac

Po   komendzie  

case

,   podawana   jest   warto

ść

,   która   ma   by

ć

  oceniana.   Mo

Ŝ

e   to   by

ć

zmienna,  lub  zdefiniowane  słowo.   Z  oczywistych   wzgl

ę

dów  wstawia   si

ę

 tam  zazwyczaj

nazw

ę

  zmiennej   –   zwi

ę

ksza   automatyczno

ść

  konstrukcji.   Je

Ŝ

eli   w   słowie   wyst

ę

puj

ą

spacje, to cało

ść

 nale

Ŝ

y otoczy

ć

 znakami podwójnego cytowania. Kolejnymi elementami

case

 s

ą

: słowo kluczowe 

in

 i lista opcji do wyboru.

Ka

Ŝ

d

ą

 z opcji umieszcza si

ę

 w nowej linii i ko

ń

czy zamykaj

ą

cym nawiasem. Je

Ŝ

eli shell

ustali zgodno

ść

 zmiennej z którym

ś

 z szablonów to wykonana zostanie komenda, b

ą

d

ź

lista   wprowadzonych   komend   umieszczonych   za   danym   ci

ą

giem   szablonów,   po   czym

obsługa 

case

 jest ko

ń

czona.

W szablonach dozwolone jest stosowanie wyra

Ŝ

e

ń

 regularnych zawieraj

ą

cych metaznaki:

*

 (dowolny napis) 

?

 (dowolny znak) 

[...]

 (okre

ś

lony zbiór znaków).

Konstrukcja  

case

  nie sprawdza, czy wszystkich  szablonów pasuj

ą

cych do testowanego

słowa/zmiennej. Je

ś

li shell natrafi na pierwszy zgodny ze zmienn

ą

 szablon to lista komend

po nim wyst

ę

puj

ą

cych jest wykonywana.

case "$1" in
   *) echo "zgodność 1";;
   *) echo "zgodność 2";;
esac

W powy

Ŝ

szym przykładzie zostanie wi

ę

c wy

ś

wietlony tylko napis „zgodno

ść

 1”.

case "$1" in
   start|uruchom)
      echo "$0 został wywołany z pierwszym argumentem:"
      echo "\"start\" lub \"uruchom\""

background image

   stop|zatrzymaj)
      echo "$0 został wywołany z pierwszym argumentem:"
      echo "\"stop\" lub \"zatrzymaj\""
   *)
      echo "$0 został wywołany z pierwszym argumentem"
      echo "nierozpoznawalnym przez składnię skryptu."
esac

Mo

Ŝ

liwe   jest   poddawanie   kilku   szablonów   alternatywnych   (poprzez   u

Ŝ

ycie   symbolu

podziału potoku 

|

), przy których zostanie wykonany ten sam ci

ą

g instrukcji.

P

ę

tla 

for

Powłoka 

bash

 oferuje dwa rodzaje p

ę

tli. Pierwszy z nich stanowi p

ę

tla 

for

. Pobiera ona,

jako parametr, list

ę

 napisów i dla ka

Ŝ

dego, jeden raz wykonuje zadeklarowan

ą

 składni

ę

.

Drugi rodzaj p

ę

tli stanowi

ą

 polecenia 

while

 i 

until

, które w odró

Ŝ

nieniu od 

for

 pobieraj

ą

wyra

Ŝ

enie   warunkowe,   jako   parametr   i   wykonuj

ą

  si

ę

  tak   długo,   jak   wyra

Ŝ

enie   jest

prawdziwe (w przypadku 

while

), lub gdy jest fałszywe (w przypadku 

until

).

Bash

  poprzez struktur

ę

 for umo

Ŝ

liwia wykonywanie p

ę

tli iteracyjnej na zbiorze warto

ś

ci.

Ka

Ŝ

da   iteracja   (powtórzenie)   wykonuje   tylko   jeden   raz   okre

ś

lony   zestaw   instrukcji   dla

ka

Ŝ

dej warto

ś

ci zbioru przekazanej w postaci parametru.

Ogólna konstrukcja p

ę

tli 

for

, któr

ą

 obsługuje powłoka 

bash

 ma nast

ę

puj

ą

c

ą

 posta

ć

:

for var in lista_słów
do
   zestaw_instrukcji
done
lista_słów

  przekazywana   jest   p

ę

tli   w   formie   parametru   po   słowie   kluczowym  

in

,

poprzedzonym nazw

ą

 zmiennej   

var

. Podczas ka

Ŝ

dej iteracji, zmienna var przechowuje

aktualn

ą

  warto

ść

  z   listy.   Pierwsza   iteracja   wykorzystuje   pierwszy   element   listy,   kolejna

drugi, trzeci i tak, i tak a

Ŝ

 do ostatniego.

Ci

ą

g instrukcji zawieraj

ą

cy zmienn

ą

 

var

, jaki ma zosta

ć

 wykonany dla ka

Ŝ

dego elementu

listy umieszcza si

ę

 pomi

ę

dzy znacznikami 

do

 i 

done

.

for i in $*
do
   echo wartość argumentu: $i
done

Wywołanie powy

Ŝ

szego skryptu z kilkoma parametrami zwróci warto

ś

ci tych parametrów

poprzedzone ci

ą

giem tekstowym.

for i in `ls *.sh`
do
   echo $i
done

Jak wida

ć

 na powy

Ŝ

szych przykładach,  

lista_słów

  mo

Ŝ

e by

ć

 reprezentowan

ą

 zmienn

ą

przechowuj

ą

c

ą

 zbiór warto

ś

ci, lub mo

Ŝ

e by

ć

 po prostu list

ą

 elementów wprowadzonych

przez u

Ŝ

ytkownika, b

ą

d

ź

 te

Ŝ

 wyprowadzonych za pomoc

ą

 zewn

ę

trznej komendy. Ka

Ŝ

dy

element   mo

Ŝ

e   by

ć

  cyklicznie   wywoływany   tylko   raz,   wraz   z   zestawem   komend,   a

Ŝ

  do

momentu, kiedy 

lista_słów

 zostanie wyczerpana.

background image

Powłoka 

bash

 umo

Ŝ

liwia tak

Ŝ

e u

Ŝ

ywanie konstrukcji p

ę

tli for w formie znanej z j

ę

zyka C:

for (( i=0; <= 5; i++ ))
do
   echo $i
done

Konstrukcja 

while 

i

 until

Inny rodzaj p

ę

tli stanowi

ą

 komendy 

while

 i 

until. 

Blok polece

ń

 obj

ę

ty działaniem p

ę

tli

while

  jest   wykonywany   w   kolejnych   cyklach   p

ę

tli   tak   długo,   jak   długo   spełniony   jest

warunek okre

ś

lony parametrem, wyst

ę

puj

ą

cym bezpo

ś

rednio po słowie 

while

.

Ogólna konstrukcja p

ę

tli 

while

, któr

ą

 obsługuje powłoka 

bash

 ma nast

ę

puj

ą

c

ą

 posta

ć

:

while komendy1
do
   komendy2
done

Opisana konstrukcja powoduje wykonanie listy polece

ń

, okre

ś

lonym w powy

Ŝ

szym zapisie

jako 

komendy1

 i warunkowe wykonanie polece

ń

 

komendy2

, obj

ę

tych działaniem p

ę

tli, które

zawarte   s

ą

  pomi

ę

dzy   słowami   kluczowymi  

do

  i  

done

.   Wykonywane   s

ą

  wi

ę

c   najpierw

polecenia komendy1,a gdy zwrócenie warto

ś

ci 0 (true) warunkuje to wywołanie instrukcji

zawartych   pomi

ę

dzy   do   i   done.   P

ę

tla   jest   wykonywana   do   momentu   otrzymywania

warto

ś

ci 0, w przeciwnym razie jest ko

ń

czona.

while [ $1 ]
do
   echo kod wyjścia: $? argumenty: $*
   shift
done

Je

Ŝ

eli   podano   niepust

ą

  warto

ść

  parametrów,   to   konstrukcja   while   wykonuje   test   ilo

ś

ci

argumentów, po czym wy

ś

wietla aktualn

ą

 ich liczb

ę

. Dopóki zwracany z testu kod wyj

ś

cia

b

ę

dzie  

0

  (true)   p

ę

tla   b

ę

dzie   si

ę

  wykonywała.   Zastosowanie   wewn

ę

trznego   polecenia

powłoki  shift   w   bloku   instrukcji   uruchamianych  po   spełnieniu   warunku  –   powoduj

ą

cego

przesuwanie   parametrów   w  lewo   i   ich   kasowanie   –   zmniejszaj

ą

cego   z  ka

Ŝ

dym   cyklem

liczb

ę

  parametrów   o   jeden   i   obni

Ŝ

aj

ą

cego   numeracj

ę

  zmiennych,   powoduje,  

Ŝ

e   p

ę

tla

b

ę

dzie wykonywała  si

ę

 do momentu anihilacji ostatniego argumentu, tj. wtedy, gdy test

zwróci warto

ść

 ró

Ŝ

n

ą

 od zera (w tym wypadku 1).

Poł

ą

czenie polecenia 

test

 z konstrukcj

ą

 

while

 równoznaczne jest u

Ŝ

yciu konstrukcji 

if-

then

.

Podczas uruchamiania procesów tworzone s

ą

 tzw. 

pidfile

, czyli pliki informuj

ą

ce o tym,

Ŝ

e dany proces jest uruchomiony. Zazwyczaj przechowuj

ą

 te

Ŝ

 one numer tego procesu.

Po zako

ń

czeniu działania programu, jego 

pidfile

 jest automatycznie kasowany.

Przy pomocy konstrukcji  

while

  mo

Ŝ

emy sprawdza

ć

 czy dane polecenie jeszcze działa i

warunkowa

ć

 wykonywanie kolejnych opartych o wyniki działania poprzednich aplikacji:

while [ -f ~/program1/pidfile ]
do
   sleep 10
done

P

ę

tla   sprawdza   istnienie   pliku,   je

ś

li   zwrócona   jest   warto

ść

 

0

  (true)   to   czeka   10   sek.   i

background image

ponownie dokonuje sprawdzenia. Konstrukcja ko

ń

czy działania w przypadku skasowania

pliku.

Je

Ŝ

eli potrzebna jest odwrotne działaj

ą

ca p

ę

tla, tzn. je

Ŝ

eli komenda ma by

ć

 wykonana do

momentu otrzymania warto

ś

ci kodu wyj

ś

cia ró

Ŝ

nego od 

0

 stosujemy konstrukcj

ę

 

until

:

until komendy1
do
   komendy2
done

Dopóki kod wyj

ś

cia  

komendy1

  b

ę

dzie zwracał warto

ść

 warto

ść

 ró

Ŝ

n

ą

 od  

0

  blok polece

ń

komendy2

, b

ę

dzie wykonywany. Po osi

ą

gni

ę

ciu warto

ś

ci 

0

, p

ę

tla zako

ń

czy swoje działanie.

until who | grep student1
do sleep 20
done
write student1 << MSG
-- zajecia z 21.01.2012 odwolane --
MSG

Dopóki u

Ŝ

ytkownik nie zaloguje si

ę

 do systemu p

ę

tl

ą

 b

ę

dzie zawiesza

ć

 działania na 20

sek. po czym uruchomia

ć

 si

ę

 ponownie. Kiedy polecenie zwróci warto

ść

 

0

 (true) działanie

p

ę

tli zostanie przerwane, a znalezionemu w systemie u

Ŝ

ytkownikowi przesłana zostanie

(za pomoc

ą

 programu 

write

) wiadomo

ść

 znajduj

ą

ca si

ę

 pomi

ę

dzy znacznikami 

<< MS

G i

MSG

.

Zadanie 1
Napisa

ć

 skrypt, który w zale

Ŝ

no

ś

ci od tego, czy uruchomił go u

Ŝ

ytkownik student, czy root

wy

ś

wietli powitalny napis. Dla u

Ŝ

ytkownika jas i marysia zwróci dwa ró

Ŝ

ne komunikaty, a

dla   pozostałych   u

Ŝ

ytkowników   wypisany   b

ę

dzie   napis,  

Ŝ

e   nie   s

ą

  oni   znani   skryptowi.

Przetestowa

ć

 działanie skryptu.

Zadanie 2
Napisa

ć

  skrypt,   który   przy   u

Ŝ

yciu   p

ę

tli  

for

  wy

ś

wietli   list

ę

  5   dowolnych   imion   z

poprzedzaj

ą

cym ich stałym tekstem.

Zadanie 3
Napisa

ć

 skrypt, który ka

Ŝ

de słowo zdania potraktuje, jako osobny element i wypisze go na

standardowym wyj

ś

ciu: "Lubie "programowa

ć

" w bash'u".

Zadanie 4
Napisa

ć

  skrypt   o   działaniu,   jak   z   zadania   2,   z   t

ą

  ró

Ŝ

nic

ą

,  

Ŝ

eby   czytanie   listy   było   ze

zmiennej.

Zadanie 5
Napisa

ć

  skrypt,   który   przy   pomocy   p

ę

tli   b

ę

dzie   wy

ś

wietlał   wszystkie   dane   z   pliku

"

im_nazw

",   który   trzeba   uprzednio   stworzy

ć

  i   wprowadzi

ć

  dowolne   dane   trzech   osób

(ka

Ŝ

da w nowej linii) wg wzoru: Imi

ę

 Nazwisko

Zadanie 6
Napisa

ć

 skrypt który sprawdzi i wypisze, które z plików katalogu domowego s

ą

 katalogami,

a które zwykłymi plikami. Zastosowa

ć

 tylko jedn

ą

 p

ę

tl

ę

.

background image

Zadanie 7
Napisa

ć

 skrypt, który przy u

Ŝ

yciu p

ę

tli for wypisze dziesi

ęć

 kolejnych warto

ś

ci.

Zadanie 8
Napisa

ć

 skrypt, w którym dwie zmienne b

ę

d

ą

 zmienia

ć

 warto

ś

ci przeciwbie

Ŝ

nie: pierwsza

od  A  do  B, a druga od  B  do  A  (A  i  B  s

ą

 cyframi). Zmiana w ka

Ŝ

dym cyklu dla obydwu

zmiennych.

Zadanie 9
Przepisa

ć

 działanie skryptu z zadania 7 z u

Ŝ

yciem p

ę

tli 

while

Zadanie 10
Napisa

ć

 skrypt wykonuj

ą

cy to samo zadanie przy u

Ŝ

yciu konstrukcji for

while [ $1 ]
do
   echo kod wyj

ś

cia: $? argumenty: $*

   shift
done

Zadanie 11
Za   pomoc

ą

  konstrukcji  

until

  wyliczy

ć

  wszystkie   warto

ś

ci   z   okre

ś

lonym   krokiem,   od

zadeklarowanej do zera.

Zadanie 12
Napisa

ć

 skrypt, który dla ka

Ŝ

dej z warto

ś

ci od 5 do 0 wykona  mno

Ŝ

enie ka

Ŝ

dej z tych

warto

ś

ci przez cyfry od 1 do 3. Wszystkie dane wy

ś

wietli

ć

 na ekranie i zapisa

ć

 do pliku z

poziomu skryptu.

Zadanie 13
Napisa

ć

 skrypt, który dla ka

Ŝ

dej linii pliku  

/etc/passwd

 wypisze wszystkie jej elementy .

Przykładowy wynik działania skryptów::

student:x:1000:1004:student:/home/student:/bin/bash
student
x
1000
..
itd.

Zadanie 14
Napisa

ć

  skrypt,   który   dla   zmiennej   tablicowej   (stworzy

ć

  zmienn

ą

  składaj

ą

c

ą

  si

ę

  z   7

elementów)   wy

ś

wietli   liczb

ę

  elementów   przechowuj

ą

cych   przez   tablic

ę

,   a   nast

ę

pnie

indeksy i przyporz

ą

dkowane im warto

ś

ci elementów, oraz wszystkie elementy nieparzyste.

Zadanie 15
Napisa

ć

  skrypt,   który   wypisze   nazwy   wszystkich   plików   katalogu   domowego   małymi

literami, a katalogów du

Ŝ

ymi.