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
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
-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
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
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