Znaki cytowania

W systemach z rodziny Unix, wyróŜnia się trzy rodzaje cytowań:

–

podwójny cudzysłów " → blokuje wszystkie poza: $, \, ` znaki specjalne pomiędzy " "

–

pojedynczy cudzysłów ' → blokuje wszystkie znaki specjalne pomiędzy ' '

–

apostrof ` → blokuje wszystkie znaki specjalne pomiędzy ` `

ZaleŜnie od sytuacji naleŜy wybrać właściwy.

$ echo "katalog $HOME"

katalog /home/student

Podstawiane są wartości zmiennych $ (substytucja zmiennych), a jedyne metaznaki o specjalnym znaczeniu to backslash \ oraz apostrof `. Pozostałe metaznaki zapisane w " "

tracą unikatowe znaczenie dla systemu. Backslash, moŜe słuŜyć np.: do zdejmowania specjalnego znaczenia znakowi stojącemu bezpośrednio za nim.

$ echo 'katalog $HOME'

katalog $HOME

Wszystkie metaznaki pomiędzy pojedynczymi cytowaniami są blokowane $ echòkatalog $HOMÈ

-bash: katalog: command not found

Wykonywane jest polecenie znajdujące się pomiędzy apostrofami. W rozumieniu bash'a spacja rozdziela komendy i ich argumenty. Zgodnie z tym, powyŜsza składania interpretowana jest jako wyświetlenie zawartości wykonanego polecenia. Pierwszy wyraz traktowany jest jako komenda, która rzecz jasna w systemie nie istnieje (co sygnalizuje powłoka katalog: command not found). Kolejnym wyrazem jest wartość zmiennej $HOME, która traktowana jest jako argument komendy.

test

Sprawdzanie podanych warunków

Program test traktuje podane mu argumenty, jako wyraŜenia logiczne i wylicza jego wartość. JeŜeli wyliczona wartość jest prawdą, to zwracany jest kod zakończenia 0 (true); jeśli nie wyraŜenie nie zostało podane bądź wyliczona wartość jest fałszywa zwracana jest wartość róŜna od zera (false).

P

rzy uŜyciu drugiej postaci polecenia z nawiasami [

] , pomiędzy nawiasami, a

wyraŜeniem musi wystąpić przynajmniej jedna spacja. MoŜliwe jest zamienne stosowanie polecenia test i nawiasów, z tego względu, Ŝe [ jest linkiem symbolicznym do polecenia test. UŜycie formy [ wyrażenie ] równowaŜne jest wywołaniu polecenia test z argumentem ].

Operatory logiczne:

WyraŜenia buduje się z warunków elementarnych, które mogą być wiązane operatorami (spójnikami logicznymi AND i OR):

-a

- koniunkcji (ang. and)

-o

- alternatywy (ang. or)

!

- negacji

(wyraŜenie) - nawiasy zapewniają moŜliwość łączenia wyraŜenia xyz w grupy $ [ wyr1 -a wyr2 -o wyr3 ]

Sprawdzanie praw dostępu, rodzaju i właściwości plików – poniŜsze warunki są spełnione (zwracana jest wartość true), jeŜeli plik stanieje i jest plikiem określonego typu

-b plik

plik jest urządzenie blokowym – plik specjalny

-c plik

plik jest znakowym plikiem specjalnym

-d plik

plik jest katalogiem

-e plik

plik istnieje

-f plik

jest plikiem normalnym (zwykłym)

-g plik

plik ma ustawiony bit (SGID) prawa do zmiany efektywnego GID

-h plik

plik jest linkiem symbolicznym

-G plik

plik jest własnością grupy do której naleŜy wywołujący test = EUID

-k plik

plik ma ustawiony bit sticky (poza userem i adminem nikt nie moŜe modyfikować plików z tą flagą)

-L plik

plik jest linkiem symbolicznym

-O plik

lik jest własnością user'a wywołującego test = EUID

-p plik

plik jest łączem nazwanym (PIPE)

-r plik

plik posiada prawo odczytu

-s plik

plik jest niezerowej wielkości

-S plik

plik jest gniazdem (ang. socket)

-u plik

plik ma ustawiony bit (SUID) prawa do zmiany efektywnego UID

-w plik

plik posiada prawa zapisu

-x plik

plik posiada prawa wykonywania

plik1 -nt plik2

plik1 jest nowszy (zgodnie z datą modyfikacji) niŜ plik2

plik1 -ot plik2

plik1 jest starszy niŜ plik2

plik1 -ef plik2

plik1 i plik2 mają te same numery urządzenia oraz i-węzła, tj. są wzajemnymi twardymi dowiązaniami

Porównania arytmetyczne:

wyr1 -eq wyr2

wyraŜenia są równe (=)

wyr1 -ne wyr2

wyraŜenia są róŜne (!=)

wyr1 -gt wyr2

wyr1 > wyr2

wyr1 -ge wyr2

wyr1 >= wyr2

wyr1 -lt wyr2

wyr1 < wyr2

wyr1 -le wyr2

wyr1 <= wyr2

wyr1 -a wyr2

oba wyraŜenia są prawdziwe (AND)

wyr1 -o wyr2

jedno wyraŜenie jest prawdziwe (OR)

! wyr

wyraŜenie jest zerowe

Sprawdzanie ciągów:

łańcuch

ciąg nie jest pusty

łańcuch 1 = łańcuch 2, łańcuch == łańcuch 2 ciągi są jednakowe łańcuch 1 != łańcuch 2

ciągi są róŜne

-z łańcuch

ciąg jest pusty

-n łańcuch

ciąg nie jest pusty

$ ls -la

-rw------- 1 student student 74 paź 30 16:45 .bash_history

-rw-r--r-- 1 student student 24 paź 15 13:04 .bash_logout

-rw-r--r-- 1 student student 191 paź 15 13:04 .bash_profile

-rw-r--r-- 1 student student 231 paź 15 13:04 .bashrc

-rw-r--r-- 1 student student 1643 paź 23 12:22 .fonts.cache-1

drwxr-xr-x 3 student student 4096 paź 30 14:34 .mc/

$ test -r .bash_profile

$ echo $?

0

$ test -r .bash_profile1

$ echo $?

1

lub analogicznie działające polecenie z tym, Ŝe sprawdzające zapis na pliku $ [ -w .bash_profile1 ] ; echo $?

0

$ [ -w .bash_profile1 ] ; echo $?

1

test -1 -gt -2 && echo prawda # jeŜeli -1 > -2 to wyświetlany jest napis: prawda

[ 1 -lt 5 -a ab != abc ] && echo prawda || echo fałsz prawda

jeŜeli obydwa wyraŜenia są spełnione to wyświetlany jest napis prawda

[ "$LOGNAME" = "student" -a "$TERM" = "xterm" ] ; echo $?

JeŜeli bieŜąca nazwa uŜytkownika i uŜywany terminal (zmienne systemowe) są takie, jak podano w wyraŜeniach to zwracana jest wartość 0, w przeciwnym przypadku 1.

expr

wykonuje obliczenie i zapisuje rezultat na standardowe wyjście.

Ze względu na to, Ŝe expr jest poleceniem zewnętrznym dla bash'a, uŜywa się je wpisując w apostrofy ` bądź teŜ stosując równowaŜną im konstrukcję $( składnia polecenia).

$ echo $(expr 5 + 5)

10

$ echo èxpr 5 + 5`

10

KaŜdy człon wyraŜenia musi być oddzielnym argumentem. Operandy mogą być liczbami lub ciągami znaków. Łańcuchów znaków nie cytuje się dla expr, choć niekiedy niezbędna jest ich ochrona przed powłoką (znaki i łańcuchy o specjalnym znaczeniu dla powłoki, np.

spacja). expr rzutuje wszystko znajdujące się po stronie operandowej na integer lub łańcuch, zaleŜnie od rodzaju operacji.

Operatory mogą być podawane jako symbole wzrostowe lub kluczowe słowa przedrostkowe. Do grupowania moŜna w zwykły sposób korzystać z nawiasów (nawiasy muszą być jednak cytowane, by ochronić je przed rozwinięciem przez powłokę).

Operatory numeryczne i relacyjne

+, - ,

Operatory arytmetyczne: dodawania, odejmowania, mnoŜenia, dzielenia, reszty z dzielenia.

*, /, % Obydwa argumenty są rzutowane na liczby. Jeśli nie jest to moŜliwe, pojawia się błąd

|, &

Operatory logiczne – OR zwraca swój pierwszy argument w wypadku gdy jest niezerowy i nie pusty, lub drugi w przeciwnym przypadku; AND zwraca swój pierwszy argument w wypadku gdy Ŝaden z argumentów nie jest zerowy ani pusty, w przeciwnym razie zwraca zero.

WyraŜenia łańcuchowe i rozpoznawane słowa kuloczwe

:

Dokonuje porównania wzorców, argumenty rzutowane są na łańcuchy, a drugi jest łańcuch: regex

uwaŜany za wyraŜenie regularne poprzedzone niejawnym ^. Następnie pierwszy argument jest dopasowywany do tego wyraŜenia regularnego. JeŜeli porównanie jest pomyślne, a regex korzysta z \( i \) to wyraŜenie : zwraca część łańcucha dopasowaną tym podwyraŜeniem.

W przeciwnym razie zwracana jest liczba dopasowanych znaków.

match łańcuch

Alternatywny sposób porównywania wzorców. Jest to identyczne z zapisem: regex

łańcuch : regex

substr łańcuch

Zwraca łańcuch będący częścią łańcucha, zaczynającą się na pozycji i o długości pozycja długość najwyŜej długość. Jeśli pozycja lub długość jest niedodatnie lub nienumeryczne, zwracany jest łańcuch pusty.

index łańcuch

Zwraca pierwszą pozycję w łańcuchu gdzie znaleźć moŜna pierwszy znak z klasy-klasa-znakowa

znakowej. Jeśli nie znaleziono Ŝadnego znaku z klasy-znakowej, zwraca 0.

length łańcuch

Zwraca długość łańcucha.

quote token

Interpretuje token jako łańcuch, nawet jeśli jest on słowem kluczowym, jak match lub operatorem jak /. UmoŜliwia to testowanie èxpr length quote "$x"' lub èxpr quote

"$x" : '.*/\(.\)'' i otrzymanie prawidłowego wyniku nawet jeśli wartością $x będzie, na przykład, operator / czy słowo kluczowe index.

Przykłady:

string='konto studenta'

expr index "$string" s

7

expr index "$string" sk

1

expr match "$string" 'konto st'

8

expr substr 'konto studenta' 5 3

o s

expr length "$string"

14

expr 5 + 10 / 2

5

expr \( 5 + 10 \) / 2

7

expr "$SHELL" : '.*'

9

Obliczanie wyraŜeń

Inną metodą obliczania wyraŜeń bez uŜywania zewnętrznych poleceń, jak opisane expr, jest uŜycie wewnętrznej konstrukcji bash'a. Metoda ta jest szybsza, poniewaŜ nie jest

wywoływany oddzielny proces.

Operatory numeryczne:

+, -, *, /, %, **

Dodawanie, odejmowanie, mnoŜenie, dzielenie,

dzielenie z reszty, potęgowanie

!, ~

Logiczna i bitowa negacja

<<, >>

Pzesunięcia bitowe

==, !=, <, >, <=, >=

porównania

&, ^, |

bitowe AND, XOR, OR

&&, ||

Logiczne AND i OR

warunek?wyrazenie1:wyrazenie2 WyraŜenia warunkowe (patrz język C) – jeśli warunek jest spełniony, to wykonywane jest wyrazenie1, w

przeciwnym razie wyrazenie2

=, *=, /=, %=, +=, -=, <<=, >>=,

Przypisania (patrz język C)

&=, ^=, |=

Konstrukcja:

$((wyraŜenie))

((wyraŜenie))

let wyraŜenie

Przykłady:

var1=1

echo $((var2=var1+1))

2

((var3=var2**(var1*3))); echo $var3

8

let var4+=2; echo $var4

2

let var4+=var1; echo $var4

4

var5=5; let var6=(var5==2?1:0) ; echo $var6

0

echo $((var=5==6?1:0))

0

Rozwijanie (ekspansja) zmiennych przez powłokę

Aby powłoka poprawnie interpretowała zmienne naleŜy precyzyjnie definiować co ma być rozwinięte np.:

$ var=1

$ echo toJest$varNaszaZmienna

toJest

Powłoka nie wie jakiej nazwy zmiennej uŜyć, czy ma to być $v, $va, czy moŜe $varNa.

Poprzez uŜycie { } moŜna prawidłowo określić ekspansję zmiennej $ echo toJest${var}NaszaZmienna

toJest1NaszaZmienna

Sposoby dzielenia łańcuchów, rozwinięcia parametryczne

Ciągi znaków moŜna dzielić w prosty sposób poprzez wbudowane komendy jak dirname, czy basename.

basename /etc/hostname

hostname

Dzieli ciąg odrzucając ścieŜkę do podanej nazwy

dirnamèwhich bash`

/bin

Dzieli ciąg odrzucając nazwy i jak w tym przypadku wypisuje tylko katalog w którym podana komenda się znajduje

Pod zmienne moŜna podstawiać komendy, w ten sposób moŜliwe jest przekierowanie wyniku wykonania konstrukcji do zmiennej środowiskowej

listaPlikow=$(ls /etc | grep host)

echo $listaPlikow

host.conf hostname hosts hosts.allow hosts.deny

Poza prostym manipulowaniem na ścieŜce dostępu, które oferują wspomniane polecenia dirname i basename, przydatne jest poznanie zaawansowanych funkcji dzielenia łańcuchów.

Rozwinięcia parametryczne (napis moŜe być określony wyraŜeniem arytmetycznym, łańcuchem znaków, poleceniem wykonywanym – w apostrofach, badź wyraŜeniem parametrycznym)

${ parametr:- napis}

WyraŜenie przyjmuje wartość zmiennej

parametr, gdy jest ona zdefiniowana i

niepusta, w przeciwnym razie wartością

wyraŜenia jest napis

${ parametr:= napis}

WyraŜenie przyjmuje wartość zmiennej

parametr, gdy jest ona zdefiniowana i

niepusta, w przeciwnym razie wartością

wyraŜenia i zmiennej parametr jest napis

${ parametr:+ napis}

WyraŜenie nie przyjmuje wartość jeśli

parametr jest niezdefiniowany lub pusty.

W przeciwnym razie wartością wyraŜenia

jest napis

${ parametr:? napis}

WyraŜenie przyjmuje wartość zmiennej

parametr, gdy jest ona zdefiniowana i

niepusta, w przeciwnym razie wartością

wyraŜenia jest rozwinięta przez powłokę

wartość zmiennej napis

${# parametr}#

zwraca długość zmiennej parametr w

znakach

${ parametr# napis}

zwraca wartość parametr po usunięciu z

niego od początku najkrótszego ciągu

pasującego do napis

${ parametr## napis}#

zwraca wartość parametr po usunięciu z

niego od początku najdłuŜszego ciągu

pasującego do napis

${ parametr% napis}#

zwraca wartość parametr po usunięciu z

niego od końca najkrótszego ciągu

pasującego do napis

${ parametr%% napis}

zwraca wartość parametr po usunięciu z

niego od końca najdłuŜszego ciągu

pasującego do napis

$ plik=/etc/hostname ; echo $plik

/etc/hostname

$ tmp1=${plik##*/} ; echo $tmp1

hostname

$ tmp2=${plik#*/} ; echo $tmp2

etc/hostname

$ tmp3=${plik%/*} ; echo $tmp3

/etc

Zadanie1.

Wykonać następujące komendy i sprawdź działanie znaków cytowania: $ echo "`ls -l $HOMÈ | grep stud |awk '{print $3,$8}'"

$ echo '`ls -l $HOMÈ | "grep stud" |awk '{print $3,$8}''

$ echòls -l $HOME | grep stud |awk '{print $3,$8}'`

Zadanie 2

Korzystając z moŜliwości przekierowywania wyników komend pod zmienne środowiskowe, oraz zaawansowanego dzielenia łańcuchów napisać krótki skrypt wyświetlający domyślną powłokę przypisaną studentowi

Zadanie 3

Stworzyć dowolną zmienną środowiskową w której występują przynajmniej dwie kropki, rozdzielone dowolnymi ciągami liter, bądź cyfr. Korzystając z metody dzielenia łańcuchów zostawić tylko część zmiennej występującej przed kropkami

Zdanie 4

Napisać składnię testującą plik /etc/hostname pod względem zwykłego typu pliku, zapisu, odczytu, niezerowej wielkości

Zdanie 5

Napisać składnię testującą czas modyfikacji pliku /etc/hostname i ~/bashrc Zdanie 6

Napisać składnię testującą następującą sytuację:

jeśli zmienna1 jest większa od zmiennej2, oraz plik /etc/host.deny ma większą objętość niŜ

plik /etc/host.allow lub modyfikacja pliku /etc/host.deny odbywała się wcześniej niŜ

/etc/host.allow to zwróć wartość true