Wyklad PI 4


UNIX
Kurs początkowy
Dr inż. Lucjan Miękina
upel.agh.edu.pl/wimir/login/
Katedra Robotyki i Mechatroniki
October 29, 2012
1/28
System operacyjny UNIX
System plików - przekierowanie wejścia/wyjścia
Przekierowanie standardowego wejścia
Jednym z poleceń mogących używać stdin jest cat. Polecenie cat wczytuje zawartość
jednego lub więcej plików i kopiuje na standardowe wyjście:
cat ls.txt
cat jest często używane do wyświetlania krótkich plików tekstowych.
Ponieważ cat może akceptować wiele plików na wejściu, można go użyć do łączenia
plików. Na przykład, jeśli odebrano długi plik podzielony na kilka części (file.txt.001,
file.txt.002, file.txt.003), to można je połączyć poleceniem:
cat file.txt.0* > file.txt
Ponieważ nazwy wieloznaczne (wildcards) są rozwijane w porządku rosnącym, pliki
składowe będą łączone w odpowiedniej kolejności.
Jeśli wywołamy  cat bez argumentów, to będzie realizowane czytanie ze
standardowego wejścia, które jest normalnie związane z klawiaturą, stąd polecenie
będzie wczytywać znaki z klawiatury. Jeśli wciśniemy Ctrl-d, to zostanie to
zinterpretowane jako koniec strumienia wejściowego (EOF) związanego z wejściem
standardowym. W wyniku tego cat skopiuje stdin na stdout, a użytkownik zobaczy
kopię wprowadzonych znaków na konsoli.
lm@arch:~% cat
testowanie cat i stdin... # Ctrl-d
testowanie cat i stdin...
lm@arch:~%
2/28
System operacyjny UNIX
System plików - przekierowanie wejścia/wyjścia
Przekierowanie standardowego wejścia
W związku z tym, polecenie cat może być stosowane do tworzenia plików tekstowych,
na przykład:
cat > file.txt
co wczytuje linie tekstu wprowadzone do momentu naciśnięcia Ctrl-d i następnie
zapisuje w pliku file.txt.
Wykorzystując sposób obsługi standardowego wejścia w poleceniu cat (oprócz
typowych argumentów będących plikami dyskowymi), można przekierować stdin:
lm@arch:~% cat < file.txt # przekierowanie
lm@arch:~% cat file.txt # ten sam efekt !
Używając operatora przekierowania, zmieniliśmy zródło danych przekazywanych na
standardowe wejście z klawiatury na plik file.txt. Rezultat jest identyczny jak przy
użyciu pojedynczej nazwy pliku, stąd nie można mówić o postępie w notacji, a tylko o
ilustracji samego mechanizmu. W przypadku innych poleceń użyteczność jest istotna.
3/28
System operacyjny UNIX
System plików - przekierowanie wejścia/wyjścia
Przetwarzanie potokowe (pipelining)
Ponieważ polecenia mogą wczytywać dane przez standardowe wejście i wysyłać
rezultaty na standardowe wyjście, możliwe staje się przetwarzanie potokowe pipelining.
Polega to na użyciu operatora potoku  | (kreska pionowa), dzięki czemu standardowe
wyjście pewnego polecenia zostaje związane ze standardowym wejściem następnego
polecenia:
lm@arch:~/tests% ls -l /usr/bin | less
...
Używając tej techniki, możemy wygodnie przeglądać rezultaty poleceń korzystających
ze stdout, wykorzystując w tym celu polecenia używające stdin (jak less).
Filtry
Potoki są często używane do realizacji złożonych operacji na danych (niemożliwych do
wykonania przez pojedyncze polecenie). Polecenie używane w ten sposób nazywa się
często filtrami. Filtry wczytują dane wejściowe, przetwarzają je w ustalony sposób i
wysyłają na swoje wyjście. Pierwszym z często wykorzystywanych jest polecenie sort.
Zastosowano je do utworzenia posortowanej listy programów wykonywalnych w
katalogach /bin i /usr/bin, po czym wyświetlono je poleceniem less:
lm@arch:~/tests% ls -l /bin /usr/bin | sort | less
Ponieważ dane wejściowe pochodziły z dwu katalogów, wyjście z polecenia ls składa
się z dwu posortowanych list, po jednej dla każdego katalogu. Wprowadzając do
potoku polecenie sort, otrzymano jedną posortowaną listę.
4/28
System operacyjny UNIX
System plików - przekierowanie wejścia/wyjścia
Filtry - używanie uniq aby wyświetlić lub pominąć powtarzające się linie
Polecenie uniq jest często używane wspólnie z sort. uniq akceptuje posortowaną listę
linii (ze stdin lub pliku dyskowego) i, domyślnie, usuwa powtarzające się linie. Tak
więc, by wyeliminować powtórzenia nazw programów występujących w katalogach /bin
i /usr/bin, należy dodać polecenie uniq do naszego potoku:
lm@arch:~% ls -l tests tests/dir1
tests:
total 12
drwxrwxr-x 2 lm lm 4096 Oct 20 22:26 dir1
drwxrwxr-x 2 lm lm 4096 Oct 16 14:15 dir2
-rw-rw-r-- 1 lm lm 18 Oct 12 10:55 file
tests/dir1:
total 4
-rw-rw-r-- 1 lm lm 18 Oct 20 22:23 file
lm@arch:~/tests% ls -l /bin /usr/bin | sort | uniq | less
Polecenie uniq zostało tu zastosowane by wyeliminować powtórzenia nazw w liście
posortowanej przez sort. Jeśli zależy nam na liście powtarzających się linii, należy użyć
opcji  -d dla uniq:
lm@arch:~/tests% ls -l /bin /usr/bin | sort | uniq -d | less
5/28
System operacyjny UNIX
System plików - przekierowanie wejścia/wyjścia
Filtry - używanie polecenia grep aby wyświetlić linie spełniające zadane kryterium
grep jest zaawansowanym narzędziem do wyszukiwania wzorców w plikach,
wywoływanym w następujący sposób:
grep wzorzec [plik...]
Jeśli grep znajdzie  wzorzec w pliku, wyświetla linie w których on występuje. Wzorce
które obsługuje grep mogą być proste (jednoznaczne ciągi znaków), lub złożone -
nazywane wyrażeniami regularnymi (regular expressions).
lm@arch:~% ls -l tests
total 12
drwxrwxr-x 2 lm lm 4096 Oct 20 22:26 dir1
drwxrwxr-x 2 lm lm 4096 Oct 16 14:15 dir2
-rw-rw-r-- 1 lm lm 18 Oct 12 10:55 file
lm@arch:~% ls -l tests | grep dir
drwxrwxr-x 2 lm lm 4096 Oct 20 22:26 dir1
drwxrwxr-x 2 lm lm 4096 Oct 16 14:15 dir2
Główne opcje polecenia grep:
-i ( ignore-case) ignorowanie wielkości znaków zarówno we wzorcu jak i plikach
wejściowych.
-v ( invert-match) odwrócenie znaczenia wzorca, by otrzymać linie nie zawierające
go.
6/28
System operacyjny UNIX
Wyrażenia regularne
Wyrażenia regularne są notacjami symbolicznymi, używanymi do identyfikacji wzorców
w tekstach. Do pewnego stopnia przypominają one mechanizm wyszukiwania plików i
katalogów z użyciem nazw wieloznacznych (wildcard). Wyrażenia regularne są
obsługiwane prze wiele poleceń i większość języków programowania. Tu ograniczymy
się do wersji definiowanej przez standard POSIX.
Głównym programem udostępnianym obsługę wyrażeń regularnych jest grep. Nazwa
 grep pochodzi od  global regular expression print . Zasadnicza funkcja grep to
przeszukiwanie plików wejściowych pod kątem wyrażenia regularnego i wyświetlenie na
wyjściu standardowym linii, które to wyrażenie zawierają.
Polecenie grep jest wywoływane w następujący sposób:
grep [opcje] regex [file...]
gdzie regex jest wyrażeniem regularnym, a główne opcje to:
-i ignorowanie wielkości znaków. Może być też użyte  ignore-case.
-v odwrócenie wzorca. Normalnie grep wyświetla linie zawierające wzorzec. Ta opcja pozwala
wyświetlić linie nie zawierające wzorca. Może być też użyte  invert-match.
-c wyświetlanie ilości wystąpień wzorca (lub braku wystąpień dla opcji -v) zamiast samych linii.
Może być też użyte  count.
-l wyświetlenie nazw plików zawierających wzorzec, zamiast linii. Może być też użyte
 files-with-matches.
-L jak opcja -l, ale powoduje wyświetlenie nazw plików nie zawierających wzorca. Może być też
użyte  files-without-match.
-n poprzedzanie każdej linii numerem w pliku. Może być też użyte  line-number.
-h dla wielu plików wejściowych, pominąć wyświetlanie ich nazw. Może być też użyte
 no-filename.
7/28
System operacyjny UNIX
Wyrażenia regularne
lm@arch:~% ls /bin | grep zip
bunzip2
bzip2
bzip2recover
gunzip
gzip
Wyrażenie regularne  zip jest poszukiwane i będzie znalezione jeśli w linii zawierającej
co najmniej 3 znaki wystąpią kolejno znaki  z ,  i i  p . Znaki w ciągu  zip są
traktowane literalnie (literal characters), tzn. reprezentują same siebie.
Poza literałami, wyrażenia regularne mogą zawierać meta-znaki (metacharacters),
które są używane do definiowania bardziej złożonych wzorców. Wśród meta-znaków
występują:
^ $ . [ ] { } - ? * + ( ) | \
wszystkie inne znaki są traktowane literalnie, z wyjątkiem backslash-a używanego do
definiowania meta sekwencji, a także do zmiany znaczenia meta-znaków na literały.
8/28
System operacyjny UNIX
Wyrażenia regularne
Reprezentowanie dowolnego znaku
Znak kropki może w wyrażeniu regularnym reprezentować dowolny, pojedynczy znak
na pozycji na której występuje. Na przykład:
lm@arch:~% ls /bin | grep  zip.
bunzip2
bzip2
bzip2recover
Zauważmy, że program gzip nie został wyświetlony, ponieważ kropka jako ostatni znak
zwiększyła ilość znaków wyrażenia, a nazwa  gzip nie posiada żadnego znaku po
frazie  zip .
Kotwice
Znaki ^ i $ są w wyrażeniach regularnych meta-znakami kotwicznymi (anchors).
Oznacza to, że warunkują wystąpienie wzorca wtedy i tylko wtedy gdy znajduje się on
na początku (^) lub na końcu linii ($):
lm@arch:~% ls /bin | grep  ^grep
grep
lm@arch:~% ls /bin | grep  grep$
egrep
fgrep
grep
9/28
System operacyjny UNIX
Wyrażenia regularne
Wyrażenia w nawiasach kwadratowych
Poza dopasowaniem każdego znaku, można sprawdzać wystąpienie pojedynczego
znaku spośród pewnego ich zbioru, zawartego w nawiasach prostokątnych. W
nawiasach tych można podać nawet znaki będące w innych kontekstach meta-znakami.
lm@arch:~% ls /bin | grep  grep Definiując zbiór [ez], wybieramy dowolną
bzegrep nazwę zawierającą ciąg  egrep lub
bzfgrep  zgrep :
bzgrep
lm@arch:~% ls /bin | grep  [ez]grep
egrep
bzegrep
fgrep
bzgrep
grep
egrep
zegrep
zegrep
zfgrep
zgrep
zgrep
Zbiór może być złożony z dowolnej liczby znaków, a meta-znaki tracą specjalne
znaczenie wewnątrz nawiasów. Są dwa przypadki, gdzie meta-znaki uzyskują nowe
znaczenie. Znak (^) oznacza negację; znak minus (-) oznacza zakres znaków.
10/28
System operacyjny UNIX
Wyrażenia regularne
Wyrażenia w nawiasach kwadratowych
Znak (^) oznacza negację tylko wtedy, gdy jest pierwszym w nawiasie kwadratowym;
w pozostałych przypadkach jest traktowany literalnie.
lm@arch:~% ls /bin | grep  [^ez]grep
bzfgrep
fgrep
zfgrep
Zakres znaków
Jeśli chcemy odnalezć nazwy plików zaczynające się od kolejnych małych liter i, j, k,
moglibyśmy użyć poleceń:
lm@arch:~% ls /bin | grep  ^[ijk] lm@arch:~% ls /bin | grep  ^[i-k]
init-checkconf init-checkconf
initctl2dot initctl2dot
ip ip
kbd_mode kbd_mode
kill kill
11/28
System operacyjny UNIX
Wyrażenia regularne
Alternatywa
Alternatywa pozwala zdefiniować zbiór wyrażeń używanych dla wzorca, podobnie do
zbioru znaków w nawiasach kwadratowych.
lm@arch:~% ls /bin | grep -E  (bze|grep)
bzegrep
bzexe
bzfgrep
bzgrep
egrep
fgrep
grep
Aby stosować alternatywę łącznie z innymi elementami wyrażenia regularnego, używa
się nawiasów okrągłych do separowania alternatywy:
lm@arch:~% ls /bin | grep -E  ^(bze|grep)
bzegrep
bzexe
grep
To wyrażenie pozwoli wyszukać nazwy plików, które zaczynają się od  bze lub  grep .
12/28
System operacyjny UNIX
Wyrażenia regularne
Kwantyfikator ? - wystąpienie elementu zero lub jeden raz
Ten kwantyfikator oznacza, że poprzedzający go element jest opcjonalny. Dla
ilustracji, rozważmy sprawdzanie poprawności numeru telefonicznego. Jest on
poprawny, jeśli ma jedną z dwu form: (nn) nnn-nn lub nn nnn-nn, gdzie n jest cyfrą.
Wyrażenie regularne powinno mieć postać:
^\(?[0-9][0-9]\)? ([0-9][0-9][0-9]-[0-9][0-9])$
Wykonując poniższe instrukcje:
lm@arch:~% echo "(88) 123-45" | grep -E  ^\(?[0-9][0-9]\)? ([0-9][0-9][0-9]-[0-9][0-9])$
(88) 123-45
lm@arch:~% echo "88 123-45" | grep -E  ^\(?[0-9][0-9]\)? ([0-9][0-9][0-9]-[0-9][0-9])$
88 123-45
lm@arch:~% echo "88 12-45" | grep -E  ^\(?[0-9][0-9]\)? ([0-9][0-9][0-9]-[0-9][0-9])$
lm@arch:~% echo "A8 123-45" | grep -E  ^\(?[0-9][0-9]\)? ([0-9][0-9][0-9]-[0-9][0-9])$
lm@arch:~% echo "[88] 123-45" | grep -E  ^\(?[0-9][0-9]\)? ([0-9][0-9][0-9]-[0-9][0-9])$
otrzymujemy zgodność jedynie w dwu pierwszych przypadkach.
W lewej części wyrażenia, po nawiasach występują znaki zapytania aby określić ich
opcjonalność (mogą ale nie muszą wystąpić). Ponieważ jednak nawiasy okrągłe są
normalnie traktowane jako meta-znaki, są one poprzedzone znakami \, aby wymusić
traktowanie ich jako literałów.
13/28
System operacyjny UNIX
Wyrażenia regularne
Kwantyfikator * - wystąpienie elementu zero lub więcej razy
Podobnie do kwantyfikatora ?, * oznacza element opcjonalny, jednak tu mogący
wystąpić dowolną ilość razy. Dla ilustracji, rozważmy sprawdzanie czy napis jest
zdaniem; tzn. czy zaczyna się od dużej litery, następnie zawiera dowolną ilość liter i
odstępów, a kończy się kropką.
Aby sprawdzić tą (bardzo prymitywną) definicję zdania, zastosujemy wyrażenie
regularne:
[[:upper:]][[:upper:][:lower:] ]*\.
Wyrażenie składa się z trzech części: wyrażenia w nawiasach kwadratowych
zawierającego klasę znaków [:upper:], wyrażenia w nawiasach kwadratowych
zawierającego klasy znaków [:upper:], [:lower:] i odstęp, a także kropkę (literalnie -
poprzedzoną znakiem \). Po drugiej części wyrażenia wystepuje meta-znak *, tak więc
w zdaniu po dużej literze wystąpi dowolna ilość liter i odstępów. Wykonując poniższe
instrukcje:
lm@arch:~% echo "This is a sentence." | grep -E  [[:upper:]][[:upper:][:lower:] ]*\.
This is a sentence.
lm@arch:~% echo "this is a sentence." | grep -E  [[:upper:]][[:upper:][:lower:] ]*\.
lm@arch:~% echo "This is a sentence" | grep -E  [[:upper:]][[:upper:][:lower:] ]*\.
lm@arch:~% echo "This is 3 sentence." | grep -E  [[:upper:]][[:upper:][:lower:] ]*\.
lm@arch:~% echo "This_is_a_sentence." | grep -E  [[:upper:]][[:upper:][:lower:] ]*\.
otrzymujemy zgodność jedynie w pierwszym przypadku.
14/28
System operacyjny UNIX
Wyrażenia regularne
Kwantyfikator + - wystąpienie elementu jeden lub więcej razy
Kwantyfikator + działa podobnie jak *, jednak wymaga co najmniej jednego
wystąpienia poprzedzającego go elementu. Poniżej pokazano wyrażenie regularne,
które będzie spełnione jedynie dla linii składających się z grup znaków alfabetu (słów),
oddzielonych pojedynczym odstępem:
^([[:alpha:]]+ ?)+$
Wykonując poniższe instrukcje:
lm@arch:~% echo "some words in a row" | grep -E  ^([[:alpha:]]+ ?)+$
some words in a row
lm@arch:~% echo "some words in a row:" | grep -E  ^([[:alpha:]]+ ?)+$
lm@arch:~% echo "3 words in a row" | grep -E  ^([[:alpha:]]+ ?)+$
otrzymujemy ponownie zgodność jedynie w pierwszym przypadku.
Klasy znaków standardu POSIX
Standard POSIX zawiera definicje klas znaków, ułatwiające stosowanie zakresów
znaków.
[:alnum:] znaki alfanumeryczne. W kodzie ASCII odpowiadają one: [A-Za-z0-9]
[:word:] jak [:alnum:], ale z dodatkiem znaku podkreślenia
[:alpha:] znaki alfabetu. W kodzie ASCII odpowiadają one: [A-Za-z]
[:blank:] znaki odstępu i tabulacji.
[:cntrl:] znaki sterujące ASCII. Zawiera znaki ASCII od 0 do 31 i znak 127.
[:digit:] cyfry. W kodzie ASCII odpowiadają one: [0-9]
[:upper:] duże litery.
[:lower:] małe litery.
15/28
[:graph:] znaki widoczne. W kodzie ASCII odpowiadają one znakom 33 do 126.
System operacyjny UNIX
Wyrażenia regularne
{} - wystąpienie elementu określoną ilość razy
Meta-znaki { i } stosuje się do określenia minimalnej i maksymalnej ilości wystąpień.
Są 4 sposoby ich użycia:
{n} sprawdza poprzedzający element, jeśli występuje on dokładnie n razy.
{n,m} sprawdza poprzedzający element, jeśli występuje on co najmniej n razy, ale nie
więcej niż m razy.
{n,} sprawdza poprzedzający element, jeśli występuje on n lub więcej razy.
{,m} sprawdza poprzedzający element, jeśli występuje on nie więcej niż m razy.
Wracając do przykładu dot. numerów telefonów, można zastosować te sposoby do
opisu powtórzeń i w efekcie uproszczenia wcześniej stosowanych wyrażeń:
^\(?[0-9]{2}\)? [0-9]{3}-[0-9]{2}$
Wykonując poniższe instrukcje:
lm@arch:~% echo "(88) 123-45" | grep -E  ^\(?[0-9]{2}\)? [0-9]{3}-[0-9]{2}$
(88) 123-45
lm@arch:~% echo "88 123-45" | grep -E  ^\(?[0-9]{2}\)? [0-9]{3}-[0-9]{2}$
88 123-45
lm@arch:~% echo "[88] 123-45" | grep -E  ^\(?[0-9]{2}\)? [0-9]{3}-[0-9]{2}$
lm@arch:~% echo "8A 123-45" | grep -E  ^\(?[0-9]{2}\)? [0-9]{3}-[0-9]{2}$
lm@arch:~% echo "88 12-45" | grep -E  ^\(?[0-9]{2}\)? [0-9]{3}-[0-9]{2}$
otrzymujemy zgodność jedynie w dwu pierwszych przypadkach.
16/28
System operacyjny UNIX
Skrypty
Skrypt powłoki (shell script) jest plikiem tekstowym zawierającym ciąg poleceń.
Powłoka wczytuje zawartość tego pliku i wykonuje polecenia tak jak byłyby one
wprowadzone bezpośrednio z linii poleceń.
Powłoka jest unikalna, jako że jest zarówno interfejsem do systemu i interpreterem
języka skryptowego. Większość operacji możliwych do wykonania z linii poleceń
można wykonać z poziomu skryptu, i odwrotnie.
Przygotowanie skryptu
Aby poprawnie przygotować i uruchomić skrypt, należy wykonać 3 czynności:
Napisać skrypt. Ponieważ skrypty powłoki są plikami tekstowymi należy użyć
edytora, najlepiej z podświetlaniem składni
Nadać skryptowi atrybut wykonywalności, używając polecenia chmod
Zapisać skrypt w katalogu, znajdującym się w ścieżce przeszukiwania (powłoka
automatycznie przeszukuje określone katalogi w celu uruchomienia programów
jeśli nie podano ich ścieżki.
Pierwszy skrypt
Zgodnie z tradycją programowania, pierwszy skrypt (wyjątkowo prosty) wyświetla
napis  Hello world .
1 #!/bin/bash
2 # This is our first script.
3 echo  Hello world!
Znaki #! definiują nazwę interpretera, który powinien zostać użyty w celu wykonania skryptu.
Każdy skrypt musi zawierać te znaki w pierwszej linii.
17/28
System operacyjny UNIX
Skrypty
Atrybut wykonywalności
Następnie należy nadać plikowi skryptu atrybut wykonywalności za pomocą polecenia
chmod:
lm@arch:~% ls -l HelloWorld
-rw-rw-r-- 1 lm users 59 10-26 11:07 HelloWorld
lm@arch:~% chmod 755 HelloWorld
lm@arch:~% ls -l HelloWorld
-rwxr-xr-x 1 lm users 59 10-26 11:07 HelloWorld
Typowe dla skryptów atrybuty to: 755 jeśli każdy użytkownik ma być uprawniony, a
700 jeśli tylko posiadacz. Poza tym, należy zezwolić na odczyt skryptu.
Lokalizacja pliku skryptu
Po ustawieniu atrybutów, można próbować uruchomienia:
lm@arch:~% HelloWorld
zsh: command not found: HelloWorld
lm@arch:~% ./HelloWorld
Hello World!
Jeśli przy wywoływaniu programu nie podano ścieżki, to system przeszukuje listę znanych
katalogów. Na tej podstawie dociera do /bin/ls gdy użytkownik wpisał jedynie ls w linii poleceń.
Katalog /bin jest na liście automatycznie przeszukiwanych katalogów, która jest przechowywana w
zmiennej środowiskowej PATH. Zmienna PATH składa się z nazw katalogów oddzielonych znakiem
dwukropka. Można ją wyświetlić:
lm@arch:~% echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin/core_perl
18/28
System operacyjny UNIX
Skrypty
Stałe i zmienne
Kiedy powłoka napotyka nową nazwę zmiennej, automatycznie tworzy zmienną i
inicjalizuje (nadaje wartość początkową), w odróżnieniu od wielu języków
programowania, w których zmienne muszą być deklarowane przed użyciem.
Zasady dot. nazw zmiennych:
Nazwy zmiennych składają się ze znaków alfanumerycznych (liter i cyfr) i znaku
podkreślenia
pierwszy znak musi być literą lub znakiem podkreślenia
odstępy i znaki interpunkcyjne nie są dopuszczalne.
Zasadniczo powłoka nie rozróżnia zmiennych i stałych; jest to sprawą podejścia
programistów. Zgodnie z konwencją nazwy stałych pisane są dużymi literami, a nazwy
zmiennych - małymi.
UWAGA: powłoka pozwala wymusić niezmienność (immutability) stałych za pomocą
wbudowanego polecenia declare z opcją -r (read-only). Na przykład, gdyby przypisać
zmiennej TITLE wartość w sposób:
declare -r TITLE="Dr in."
powłoka nie pozwoli na zmianę wartości TITLE.
Przypisywanie wartości do zmiennych i stałych
Przypisanie polega na zapisie wartości w obszarze pamięci zajmowanym przez
zmienną/stałą:
zmienna=wartosc
gdzie zmienna jest nazwą zmiennej/stałej, a wartosc jest łańcuchem znaków.
19/28
System operacyjny UNIX
Skrypty
Odmiennie od większości języków programowania, powłoka nie śledzi typu danych
podstawianych do zmiennych, lecz traktuje je jako łańcuchy znaków. Można jedynie
wymusić podstawienie do zmiennych całkowitych, stosując polecenie declare z opcją -i.
UWAGA: nie może być spacji między nazwą zmiennej, znakiem = i podstawianą
wartością.
lm@arch:~% nazwa=Luc # podstaw "Luc" do zmiennej nazwa
lm@arch:~% echo $nazwa
Luc
lm@arch:~% PI=3.1415 # podstaw 3.1415 do zmiennej PI
lm@arch:~% echo PI # brak $ przed nazwa zmiennej !
PI
lm@arch:~% echo $PI
3.1415
lm@arch:~% b="a string" # spacje musza wystepowac w cudzyslowach
lm@arch:~% c="Nazywam sie $nazwa" # zmienne sa zastepowane wartosciami
lm@arch:~% echo $c
Nazywam sie Luc
lm@arch:~% d=$(ls -l Hello*) # rezultat polecenia
lm@arch:~% echo $d
-rw-r--r-- 1 lm users 59 10-26 11:07 HelloWorld
-rwxr-xr-x 1 lm users 62 10-26 11:07 HelloWorld~
lm@arch:~% e=$((5 * 7)) # wyrazenie arytmetyczne
lm@arch:~% echo $e
35
lm@arch:~% f="\t\tA name: $name\n" # znaki tabulacji i nowej linii
20/28
System operacyjny UNIX
Skrypty
Funkcje powłoki
Rozbudowane skrypty zwykle składają się z wielu operacji, które mogą być zapisane w
postaci oddzielnych skryptów (w tym samym katalogu na ścieżce zdefiniowanej w
zmiennej PATH), lub umieszczone jako funkcje powłoki (shell functions) w tekście
skryptu. Funkcje powłoki są  mini-skryptami - częściami większego skryptu,
mogącymi działać jak samodzielne programy.
Funkcje powłoki mają dwie równoważne formy:
function nazwa { nazwa () {
polecenia polecenia
return return
} }
gdzie nazwa jest nazwą funkcji, a polecenia są ciągiem poleceń do wykonania.
1 #!/bin/bash
2 # A script with functions.
3 function F1 {
4 echo  In F1 !
5 return
6 } lm@arch:~% ./ShellFuns
7 F2 () {
In F2 !
8 echo  In F2 !
In F1 !
9 return
10 }
11 # Main program starts here
12 F2
13 F1
21/28
System operacyjny UNIX
Skrypty
Zmienne lokalne
Dotychczas prezentowane skrypty używały zmiennych globalnych, które są widoczne z
każdego miejsca skryptu i istnieją przez cały czas jego działania. Ma to pewne zalety,
ale nie kompensują one problemów, szczególnie w przypadku funkcji powłoki.
Wewnątrz funkcji powłoki lepiej jest stosować zmienne lokalne, które są widoczne
tylko wewnątrz funkcji i przestają istnieć po zakończeniu wykonywania się jej.
1 #!/bin/bash
Dla zmiennych lokalnych programista
2 # A script with local variables.
może użyć nazw już istniejących poza
3 var=G1
4 function F1 { daną funkcją powłoki (globalnych lub
5 local var
lokalnych), bez powodowania konfliktów.
6 var=F1
Uzyskuje się w ten sposób niezależność
7 echo "In F1: var=$var"
funkcji powłoki (możliwość użycia kodu w
8 return
9 }
innych miejscach).
10 F2 () {
Zmienne lokalne definiuje się poprzedzając
11 local var
nazwę zmiennej słowem local. Taka zmi-
12 var=F2
enna nie istnieje poza funkcją, w której ją
13 echo "In F2: var=$var"
14 return zdefiniowano.
15 }
lm@arch:~% ./LocalVars
16 # Main program starts here
In Main: var=G1
17 echo "In Main: var=$var"
In F2: var=F2
18 F2
19 F1 In F1: var=F1
22/28
System operacyjny UNIX
Skrypty
Wyrażenia plikowe
Wyrażenia pozwalające określić status pliku:
f1 -ef f2 f1 i f2 mają ten sam numer węzła (inode number) (dwa twarde dowiązania
prowadzą do tego samego pliku)
f1 -nt f2 f1 jest nowszy niż f2
f1 -ot f2 f1 jest starszy niż f2
-b file file istnieje i jest plikiem specjalnym (urządzenie blokowe)
-c file file istnieje i jest plikiem specjalnym (urządzenie znakowe)
-d file file istnieje i jest katalogiem
-e file file istnieje
-f file file istnieje i jest plikiem zwykłym
-L file file istnieje i jest dowiązaniem symbolicznym
-p file file istnieje i jest plikiem nazwanego potoku
-r file file istnieje i ma atrybut odczytu dla użytkownika efektywnego (effective user)
-s file file istnieje i ma rozmiar większy od zera
-S file file istnieje i jest plikiem gniazda sieciowego
-w file file istnieje i ma atrybut zapisu dla użytkownika efektywnego (effective user)
-x file file istnieje i jest wykonywalny dla użytkownika efektywnego (effective user).
23/28
System operacyjny UNIX
Skrypty
Kod zakończenia
Polecenia (w tym skrypty i funkcje powłoki) zwracają do systemu wartość, nazywaną
kodem zakończenia (exit status). Jest to wartość całkowita z przedziału od 0 do 255,
oznaczająca poprawne lub nie wykonanie polecenia. Zgodnie z konwencją, zero
oznacza sukces, a każda inna wartość jakiś błąd. Powłoka pozwala odczytać kod
zakończenia:
lm@arch:~% ls -l /usr/bin/ > ls.txt
lm@arch:~% echo $?
0
lm@arch:~% ls -l /user/bin/ > ls.txt
ls: cannot access /user/bin/: No such file or directory
lm@arch:~% echo $?
2
Rozgałęzienia - instrukcja if
Instrukcja if ma postać:
if sterujace; then
polecenia
[elif sterujace; then
polecenia]
[else
polecenia]
fi
gdzie sterujace są ciągiem poleceń sterujących, a polecenia są ciągiem poleceń
wykonywanych warunkowo.
24/28
System operacyjny UNIX
Skrypty
Skrypt demonstrujący wybrane wyrażenia plikowe.
1 #!/bin/bash
2 # TestFile: Evaluate the status of a file
3 FILE=~/.bashrc
4 if [ -e "$FILE" ]; then
5 if [ -f "$FILE" ]; then
6 echo "$FILE is a regular file."
7 fi
8 if [ -d "$FILE" ]; then
9 echo "$FILE is a directory."
10 fi
11 if [ -r "$FILE" ]; then
12 echo "$FILE is readable."
13 fi
14 if [ -w "$FILE" ]; then
15 echo "$FILE is writable."
16 fi
17 if [ -x "$FILE" ]; then
18 echo "$FILE is executable/searchable."
19 fi
20 else
21 echo "$FILE does not exist"
22 exit 1
23 fi
24 exit
lm@arch:~% ./TestFile
/home/lm/.bashrc is a regular file.
/home/lm/.bashrc is readable.
/home/lm/.bashrc is writable.
25/28
System operacyjny UNIX
Skrypty
Polecenie test
Poleceniem najczęściej używanym razem z instrukcją if jest test. test wykonuje różne
testy i porównania. Ma ono dwie równoważne formy:
test wyrazenie
i bardziej popularną:
[ wyrazenie ]
gdzie wyrazenie jest pewnym wyrażeniem dającym wynik prawda lub fałsz. Polecenie
test zwraca wartość zero gdy wyrażenie jest spełnione, a wartość jeden gdy wyrażenie
nie jest spełnione.
Nowsza wersja polecenia test
Nowe wersje powłok (np. bash) zawierają złożone polecenie, będące wzbogaconą
wersją polecenie test. Składnia jest następująca:
[[ wyrazenie ]]
gdzie, podobnie do test, wyrazenie jest pewnym wyrażeniem dającym wynik prawda
lub fałsz. Polecenie [[ ]] obsługuje wszystkie wyrażenia polecenia test, a dodatkowo
nowe wyrażenie tekstowe:
tekst =~ regex
które zwraca wartość logicznej prawdy gdy tekst jest zgodny z wyrażeniem regularnym
regex. Ma to wiele zastosowań, np. sprawdzenie zgodności danych z wzorcami.
26/28
System operacyjny UNIX
Skrypty
Wyrażenia tekstowe (łańcuchowe)
Do operacji na łańcuchach znaków stosuje się następujące wyrażenia:
string łańcuch string nie jest pusty
-n string długość łańcucha jest większa od zera
-z string długość łańcucha jest równa zero
s1 == s2 łańcuchy s1 i s2 są identyczne. Można stosować pojedyncze i podwójne znaki
równości, ale preferowane są podwójne
s1 != s2 łańcuchy s1 i s2 nie są identyczne
s1 > s2 gdy łańcuchy są posortowane, s1 wystąpi po s2
s1 < s2 j.w., s1 wystąpi przed s2
Na przykład:
1 #!/bin/bash
2 # TestStrings: evaluate the value of a string
3 ANSWER=yes
4 if [ -z "$ANSWER" ]; then
UWAGA: operatory > i <
5 echo "There is no answer." >&2
6 exit 1
muszą wystąpić w cudzysłowach
7 else
wewnątrz polecenia test. W prze-
8 if [ "$ANSWER" == "yes" ]; then
ciwnym razie zostałyby zinterpre-
9 echo "The answer is YES."
10 elif [ "$ANSWER" == "no" ]; then towane jako przekierowania.
11 echo "The answer is NO."
12 else
13 echo "The answer is UNKNOWN."
14 fi
15 fi
27/28
System operacyjny UNIX
Skrypty
Wyrażenia całkowite Na przykład:
W wyrażeniach całkowitych można
1 #!/bin/bash
2 # TestInts: evaluate the value of an integer.
użyć następujących konstrukcji:
3 INT=-5
i1 -eq i2 i1 jest równe i2
4 if [ -z "$INT" ]; then
5 echo "INT is empty." >&2
i1 -ne i2 i1 nie jest równe i2
6 exit 1
7 fi
i1 -le i2 i1 jest mniejsze lub równe i2
8 if [ $INT -eq 0 ]; then
9 echo "INT is zero."
i1 -lt i2 i1 jest mniejsze od i2
10 else
11 if [ $INT -lt 0 ]; then
i1 -ge i2 i1 jest większe lub równe i2
12 echo "INT is negative."
13 else
i1 -gt i2 i1 jest większe od i2.
14 echo "INT is positive."
15 fi
16 if [ $((INT % 2)) -eq 0 ]; then
17 echo "INT is even."
18 else
19 echo "INT is odd."
20 fi
21 fi
Linia 16 pokazuje sposób określenia czy liczba jest parzysta/nieparzysta. Służy do
tego dzielenie modulo 2, którego rezultatem jest reszta z dzielenia liczby przez 2.
28/28


Wyszukiwarka

Podobne podstrony:
Wyklad PI 5
Wyklad PI 1 cz 2
Wyklad PI
Wyklad PI 9
Wyklad PI 3
Wyklad PI 2 cz 2
Wyklad PI 8
Wyklad PI 2 cz 1
Wyklad PI
Sieci komputerowe wyklady dr Furtak
Wykład 05 Opadanie i fluidyzacja
WYKŁAD 1 Wprowadzenie do biotechnologii farmaceutycznej
mo3 wykladyJJ

więcej podobnych podstron