Uniksowe interpretery polece´ n
Witold Paluszy´nski Katedra Cybernetyki i Robotyki
Politechnika Wroc lawska
http://www.kcir.pwr.edu.pl/~witold/
1995–2013 Ten utw´or jest dost
epny na licencji֒
Creative Commons Uznanie autorstwa- Na tych samych warunkach 3.0 Unported Utw´or udost
epniany na licencji Creative Commons: uznanie autorstwa, na tych֒
samych warunkach. Udziela si
e֒zezwolenia do kopiowania, rozpowszechniania i/lub modyfikacji tre´sci utworu zgodnie z zasadami w/w licencji opublikowanej przez Creative Commons. Licencja wymaga podania oryginalnego autora utworu, a dystrybucja materia l´ow pochodnych mo˙ze odbywa´c si
e֒tylko na tych samych warunkach (nie mo˙zna zastrzec, w jakikolwiek spos´ob ograniczy´c, ani rozszerzy´c praw do nich).
Interpretery polece´ n w systemach operacyjnych
Interpreter polece´n jest programem funkcjonujacym jako interfejs֒
u˙zytkownika w systemach operacyjnych. Jego rol
a֒jest wykonywanie polece´n u˙zytkownika, kt´orych celem jest zwykle uruchomienie jakiego´s programu.
Funkcje interpretera polece´n mo˙zna wi
ec stre´sci´c jako: czytanie polece´֒ n i wykonywanie program´ow.
W prehistorycznych systemach operacyjnych interpretery polece´n mia ly form e֒
szczatkow֒
a, zw laszcza w systemach przeznaczonych do pracy wsadowej, i nie֒
zawsze by ly odr
ebnymi programami. Potem jednak, w miar֒
e֒rozwoju
interakcyjnych system´ow operacyjnych, uzyska ly pe lne prawa obywatelskie, i by ly rozbudowywane o mechanizmy u latwiaj
ace prac֒
e֒u˙zytkownikom interakcyjnym.
Uniksowe interpretery polece´n zajmuj
a֒szczeg´oln a֒pozycj
e, poniewa˙z ich j֒
ezyk֒
polece´n ma wiele konstrukcji typu programistycznego, umo˙zliwiaj
acych pisanie֒
zaawansowanych zada´n wsadowych — skrypt´ow. Jednocze´snie maj a֒wiele mechanizm´ow u latwiaj
acych interakcyjn֒
a֒prac
e֒z systemem. W tradycji system´ow uniksowych interpreter polece´n nazywany jest shell-em, czyli skorup
a֒
izoluj ac֒
a֒u˙zytkownika od j
adra systemu, kt´ore wykonuje jego w la´sciwe funkcje.֒
Uniksowe interpretery polece´n — wstep֒ 3
Polecenia uniksowego interpretera polece´ n
Poleceniem mo˙ze by´c wywo lanie jakiego´s programu zewnetrznego, lub֒
polecenia wbudowanego (albo funkcji) interpretera polece´n. Wi ekszo´s´c֒
czynno´sci w systemach uniksowych realizuj
a֒programy zewn
etrzne, polece´n֒
wbudowanych istnieje zaledwie garstka. Polecenia mog
a֒mie´c argumenty przekazywane w wierszu wywo lania (zwanym wektorem argument´ow):
who # program
ls -l # program z argumentem
/bin/ps -ef # program z pelna sciezka pliku ./oblicz maj.txt # program z katalogu biezacego
set -x # polecenie wbudowane z argumentem
Wykonanie programu powoduje utworzenie oddzielnego procesu, kt´ory jest podprocesem procesu interpertera polece´n. Natomiast wykonanie polecenia wbudowanego lub funkcji odbywa si
e֒w ramach procesu interpretera polece´n.
Uniksowe interpretery polece´n — podstawowe mechanizmy 4
Uruchamianie podproces´ ow
Przy interakcyjnej pracy z interpreterem polece´n mo˙zliwa jest manipulacja podprocesami uruchomionymi przez dany interpreter. Mo˙zna zobaczy´c list e֒
podproces´ow, i ka˙zdy z nich zatrzyma´c, a tak˙ze wznowi´c, zar´owno jako zadanie w tle jak i w pierwszym planie.
acroread datasheet.pdf &
firefox http://www.google.pl/ &
jobs fg %<n>
bg %<n>
stop %<n> # tylko C-shell
Podprocesy identyfikowane s
a֒kolejnymi liczbami, a w odwo laniu do nich piszemy numer podprocesu poprzedzony znakiem procenta.
Uniksowe interpretery polece´n — podstawowe mechanizmy 5
Globbing — dopasowanie nazw plik´ ow
Interpreter polece´n realizuje tzw. globbing, polegajacy na dopasowaniu֒
nastepuj֒
acych znak´ow: * ? [a-zA-Z_] do nazw plik´ow:֒
wc *.c
echo obraz?.pgm # wynik: obraz1.pgm obraz2.pgm ls -l *.[cho]
Wa˙zne jest zrozumienie, ˙ze globbing jest mechanizmem shella, a nie og´oln
a֒konwencj
a. Na przyk lad, mechanizm ten mo˙ze z jakich´s powod´ow nie֒
zadzia la´c, i wtedy wzorzec nazwy pliku jest tylko zwyk lym stringiem, nie majacym nic wsp´olnego z odpowiadaj֒
acymi mu nazwami istniej֒
acych plik´ow:֒
$ ls try_r*.c
try_readdir.c try_realloc.c try_regex.c
$ ls ’try_r*.c’
ls: cannot access try_r*.c: No such file or directory
Uniksowe interpretery polece´n — podstawowe mechanizmy 6
Potoki
Potok (pipeline) to r´ownoleg le uruchomienie dw´och lub wi
ecej polece´n֒
z szeregowym po l
aczeniem ich wyj´s´c i wej´s´c:֒
who
who | wc -l
who | tee save | wc -l
Zapis potoku sprawia skromne wra˙zenie, lecz w potokach tkwi wielka moc.
Bierze si
e֒ona po pierwsze z bardzo porz
adnej implementacji, dzi֒
eki kt´orej przez֒
potok mo˙ze przep lyn
a´c֒ nieograniczona ilo´s´c danych,1i mo˙ze on pracowa´c przez dowolnie d lugi czas. W tym czasie poszczeg´olne procesy pracuj
a֒
r´ownolegle, a system synchronizuje ich prac e, usypiaj֒
ac te, kt´ore czytaj֒
a֒lub zapisuj
a֒dane zbyt szybko. Nast
epnie system budzi je w spos´ob przezroczysty,֒
gdy pozosta le procesy nad
a˙zy ly z przetworzeniem tych danych.֒
Drugie ´zr´od lo tej mocy to zestaw narz
edzi do przetwarzania tekst´ow Unixa,֒
dzia laj
acych w trybie input/output, dzi֒
eki kt´orym wiele zada´n w systemie Unix֒
mo˙zna wykona´c za pomoc
a֒tych narz
edzi odpowiednio po l֒
aczonych potokami.֒ 1Niezale˙znie od ich rzeczywistej, zaimplementowanej w systemie pojemno´sci potoku.
Uniksowe interpretery polece´n — podstawowe mechanizmy 7
Listy
Lista to po laczenie polece´n (´sci´slej: potok´ow) sp´ojnikami: ;, &, ||, &&֒
cc prog.c ; echo kompilacja zakonczona cc prog.c & echo kompilacja uruchomiona grep pieniadze msg.txt && echo sa pieniadze grep pieniadze msg.txt || echo nie ma pieniedzy
Priorytety sp´ojnik´ow: | — najwy˙zszy, ||,&& — ´sredni, ;,& — najni˙zszy.
Zestaw polece´n mo˙zna wzi
a´c֒ w nawiasy, aby te priorytety zmieni´c:
date; who | wc (date; who) | wc { date; who;} | wc U˙zycie nawias´ow okr
ag lych ma dodatkowy efekt w postaci utworzenia֒
dodatkowej kopii interpretera polece´n, b ed֒
acym podprocesem procesu֒
g l´ownego, kt´ory wykonuje list
e֒w nawiasie. Nawiasy klamrowe powoduj a֒
wykonanie listy w procesie bie˙z
acego interpretera polece´n, jednak wymagaj֒
a֒
u˙zycia separator´ow sk ladniowych.
Uniksowe interpretery polece´n — podstawowe mechanizmy 8
Przekierowania wej´scia/wyj´scia
W systemach uniksowych procesy moga֒mie´c otwarte strumienie danych wej´scia/wyj´scia, zwane r´ownie˙z deskryptorami plik´ow, kt´ore s
a֒numerowane sekwencyjnie od 0 wzwy˙z. Dla proces´ow uruchamianych na terminalu deskryptory 0, 1, i 2 (nazywane odpowiednio stdin, stdout, i stderr) s
a֒
w czasie inicjalizacji procesu przyporz
adkowane do klawiatury i ekranu terminala.֒
Interpreter polece´n posiada mechanizm przekierowania tych strumieni w taki spos´ob, ˙ze otwierane s
a֒pliki na dysku i dane s
a֒przez proces czytane z, lub zapisywane na tych plikach. Podstawowa forma:
./prog < plik_wejscia > plik_wyjscia 2> plik_bledow Skierowania strumieni wej´scia i wyj´scia maj
a֒jeszcze szereg innych postaci, z kt´orymi warto si
e֒zapozna´c. Przyk lady:
./prog >> plik_wyjscia # stdout dopis.na kon.pliku ./prog > /dev/null # stdout calk. ignorowane ./prog > plik_wyjscia 2>&1 # stderr do tego samego pliku ./prog 2>&1 > /dev/null # stdout ign.,stderr na stdout
Uniksowe interpretery polece´n — podstawowe mechanizmy 9 Uniksowe interpretery polece´n — podstawowe mechanizmy 10
Skrypty interpretera komend
Skryptem nazywamy plik zawierajacy zestaw polece´֒ n interpretera. Skrypt mo˙ze zawiera´c jedno lub wi
ecej polece´n (albo potok´ow, list), w jednym lub֒
wiecej wierszy. Na przyk lad, chcemy policzy´c liczb֒
e֒u˙zytkownik´ow w l aczonych֒
do systemu w nast epuj֒
acy (wcale nienajprostszy) spos´ob:֒
who | wc -l
Skrypt mo˙zna uruchomi´c, wywo luj
ac interpreter polece´n (obecny na wi֒
ekszo´sci֒
system´ow jako /bin/sh), z nazw
a֒skryptu jako argumentem:
echo ’who | wc -l’ > ilu_userow.sh sh ilu_userow.sh
. ilu_userow.sh Forma z kropk
a֒nie wywo luje dodatkowego procesu interpretera komend; skrypt wykonywany jest przez ten sam interpreter, w kt´orym polecenie zosta lo wpisane.
Uniksowe interpretery polece´n — pisanie prostych skrypt´ow 11
Pliki wykonywalne
Mo˙zemy nada´c plikowi ilu_userow.sh atrybut wykonywalno´sci x. Wtedy mo˙zna spowodowa´c wykonanie skryptu przez u˙zycie nazwy pliku jako polecenia:
chmod +x ilu_userow.sh ./ilu_userow.sh W tym przypadku bie˙z
acy interpreter polece´n wywo la drugi interpreter dla֒
wykonania tego skryptu. Normalnie b
edzie to druga instancja tego samego֒
programu, kt´ora w systemie b
edzie podprocesem procesu bie˙z֒
acego. Przy tej֒
formie wywo lania nie ma mo˙zliwo´sci spowodowania, aby skrypt zosta l wykonany przez nasz macierzysty shell.
Uniksowe interpretery polece´n — pisanie prostych skrypt´ow 12
Zmienna PATH
W powy˙zszym przyk ladzie nazwa pliku zosta la podana w postaci wzgl ednej֒
´scie˙zki do pliku, kt´ory znajduje si
e֒w katalogu bie˙z
acym. Wymusza to֒
wywo lanie pliku o podanej nazwie. Nie mo˙zemy poda´c nazwy pliku ilu_userow.shbez podania ´scie˙zki katalog´ow (przynajmniej szcz
atkowej).֒
Plik wykonywalny zostanie uruchomiony tylko wtedy, gdy znajduje si e֒
w katalogu wymienionym na li´scie katalog´ow pami
etanych w zmiennej PATH:֒
./ilu_userow.sh # poprawne
ilu_userow.sh # sh: ilu_userow.sh: not found
PATH=$PATH:. # dopisz biezacy katalog na koniec PATH ilu_userow.sh # poprawne
Zwr´o´cmy uwag
e֒— mo˙zna odwo la´c si
e֒do katalogu bie˙z
acego przez symboliczn֒
a֒
nazwe֒kropki. Zwyczajowo jednak, katalogu bie˙z
acego nie umieszcza si֒
e֒na standardowej ´scie˙zce katalog´ow programowych pami
etanej w zmiennej PATH.֒
Mo˙znaby to zrobi´c dla wygody, wpisuj
ac polecenie do pliku startowego shella.֒
Jednak jest to uwa˙zane za pewne zagro˙zenie, poniewa˙z w trakcie pracy mo˙zna w spos´ob niezamierzony wywo la´c jaki´s program z bie˙z
acego katalogu. Je´sli jest֒
to konieczne, to kropka powinna znajdowa´c si
e֒na ko´ncu ´scie˙zki katalog´ow.
Uniksowe interpretery polece´n — pisanie prostych skrypt´ow 13
Inne zmienne systemowe
Jak widzieli´smy, zmienna PATH pe lni w uniksowym interpreterze polece´n szczeg´oln
a֒rol
e. Jest szereg takich zmiennych, wykorzystywanych w r´o˙znych֒
rolach przez r´o˙zne cz
e´sci systemu Unix:֒
PATH ´scie˙zka wyszukiwania program´ow interpretera polece´n TERM identyfikator typu terminala, na kt´orym wykonuje si
e֒ program;
przydatny gdy program chce wykona´c jak a´s֒ operacj
e֒ na ekranie terminala, np. zgaszenie ekranu, lub wy´swietlanie tekstu w okre-
´slonej pozycji
MAIL ´scie˙zka do pliku z systemow a֒skrzynk
a֒pocztow
a֒u˙zytkownika PAGER okre´slenie programu, kt´ory nale˙zy wywo la´c w celu wy´swietlania
tekstu ekran po ekranie, np. man
EDITOR okre´slenie programu, kt´ory nale˙zy wywo la´c w celu edycji pliku zainicjowanej przez niekt´ore programu, np. crontab
LANG nazwa lokalizacji u˙zytkownika, okre´slaj aca j֒
ezyk i konwencje na-֒
rodowe I szereg innych.
Uniksowe interpretery polece´n — pisanie prostych skrypt´ow 14
Najprostsze skrypty
Skrypty pisze sie֒w celu automatycznego, powtarzalnego wykonania pewnych operacji. Ma to sens, gdy ten zestaw operacji jest d lugi i/lub skomplikowany.
Jakkolwiek do´swiadczeni u˙zytkownicy pisz
a֒rozbudowane i z lo˙zone skrypty (a z up lywem czasu rozbudowuj
a֒je cz
esto do monstrualnych rozmiar´ow), to֒
najwi
eksza przydatno´s´c skrypt´ow jest w automatyzacji prostych czynno´sci,֒
kt´orych nie chcemy ka˙zdorazowo pisa´c po kawa lku, a ich napisanie w postaci skryptu jest trywialne.
Przyk lady prostych skrypt´ow:
echo Do systemu jest zalogowanych who | wc -l
echo uzytkownikow.
echo W katalogu znajduje sie ls -1 | wc -l
echo plikow.
Uniksowe interpretery polece´n — pisanie prostych skrypt´ow 15
Polecenia zagnie˙zd˙zone
W powy˙zszych przyk ladach dzia lanie skryptu opiera lo sie֒na tym, ˙ze zar´owno programy systemowe, jak i polecenie echo, wy´swietlaj
a֒swoje komunikaty na wyj´sciu stdout, i u˙zytkownik widzi je l
acznie.֒
Mo˙zna wykorzysta´c mechanizm polece´n zagnie˙zd˙zonych aby po l
aczy´c teksty֒
wy´swietlane przez program z innymi tekstami. Mo˙zna zagnie´zdzi´c dowolne polecenie w dowolnym miejscu innego, przez obj
ecie go znakami apostrof´֒ ow wstecznych ‘...‘ (backquote). Jest ono wykonywane przez drug
a֒instancj e֒
interpretera polece´n przed rozpocz
eciem wykonywania polecenia g l´ownego.֒
Polecenie zagnie˙zd˙zone mo˙ze wykona´c dowolne operacje, a system zbiera wynik jego pracy w postaci wysy lanych na wyj´scie znak´ow, a nast
epnie podmienia֒
tre´s´c polecenia (razem z apostrofami wstecznymi) otrzymanym ci
agiem znak´ow.֒
Zmodyfikowana wersja poprzednich skrypt´ow:
echo Do systemu jest zalogowanych ‘who|wc -l‘ uzytkownikow echo W katalogu znajduje sie ‘ls -1 | wc -l‘ plikow.
Dodatkow a֒korzy´sci
a֒tej wersji jest wy´swietlanie ca lo´sci w jednym wierszu, poniewa˙z mechanizm zagnie˙zd˙zania zamienia znaki nowej linii na spacje.
Uniksowe interpretery polece´n — pisanie prostych skrypt´ow 16
Zmienne shella
Zmienne systemowe typu PATH albo LANG nie sa֒niczym szczeg´olnym.
Zmienn
a֒mo˙zna utworzy´c w dowolnym momencie, bez deklarowania, przypisuj ac֒
jej jak
a´s֒ warto´s´c. Mo˙zna r´ownie˙z przypisa´c warto´s´c istniej
acej zmiennej,֒
zastepuj֒
ac poprzedni֒
a֒warto´s´c. Aby obliczy´c warto´s´c zmiennej trzeba u˙zy´c wyra˙zenia ze znakiem dolara przed nazw
a֒zmiennej.
a=5 # WAZNE: zadnych spacji przed i za "="
echo zmienna a ma wartosc $a Mo˙zna u˙zy´c zmiennych aby skonstruowa´c kolejn
a֒(niekoniecznie lepsz a) wersj֒
e֒
poprzednich przyk ladowych skrypt´ow:
n_userow=‘who | wc -l‘
echo Do systemu jest zalogowanych $n_userow uzytkownikow.
n_plikow=‘ls -1 | wc -l‘
echo W katalogu znajduje sie $n_plikow plikow.
Zmienne interpretera polece´n maj
a֒zasadniczo warto´sci tekstowe. Je´sli program chce odczyta´c ze zmiennej warto´s´c liczbow
a, to musi sam j֒
a֒sobie zdekodowa´c.
Uniksowe interpretery polece´n — operacje na zmiennych 17
Pu lapki ze zmiennymi
Zmiennych shella uniksowego nie trzeba (ani nie mo˙zna) deklarowa´c. Co gorsza jednak, dopuszczalne jest odwo lanie si
e do nieistniej֒
acej zmiennej. Nie֒
jest to b l
ad, tylko daje warto´s´c pustego stringa. Ten mechanizm powoduje, ˙ze֒
mo˙zna pa´s´c ofiar a֒b l
edu wynikaj֒
acego z odwo lania si֒
e֒do niew la´sciwej zmiennej.
Przyk lad:
n_plikow=‘ls -1 | wc -l‘
echo W katalogu znajduje sie $n_pilkow plikow.
W powy˙zszym przyk ladzie zobaczymy komunikat z pustym miejscem zamiast liczby plik´ow, ale w og´olno´sci mo˙ze to by´c niew la´sciwa warto´s´c (np. poprzednia).
Niestety, jest to nieuleczalna choroba shella uniksowego. Co prawda istnieje flaga interpretera polece´n (-u) wymuszaj
aca b l֒
ad w takich przypadkach֒
(patrz poni˙zej). Jednak domy´slnie flaga ta nie jest ustawiona, zatem mo˙zna j a֒
ustawia´c dowoln a֒liczb
e֒razy w r´o˙znych miejscach, a wci a˙z֒ b
edziemy mieli do֒
czynienia z sytuacjami, gdzie flaga b
edzie nieustawiona.֒
Uniksowe interpretery polece´n — operacje na zmiennych 18
Polecenie read
Polecenie echo jest wygodnym narzedziem komunikacji skryptu֒
z u˙zytkownikiem. Aby jednak odczyta´c odpowied´z u˙zytkownika, potrzebny jest jaki´s inny mechanizm, na przyk lad polecenie read. Wczytuje ono jeden wiersz ze standardowego wej´scia (normalnie po l
aczonego z klawiatur֒
a֒u˙zytkownika), i podstawia pod podan
a֒zmienn a.֒
Przyk lad:
echo Podaj adres IP bramy domyslnej w sieci lokalnej read brama
route add default gw $brama
W og´olnym przypadku polecenie read czyta ca ly wiersz z wej´scia, ale dekoduje go na
”s lowa”, i podstawia nimi kolejne podane zmienne. Je´sli s l´ow b edzie za֒
ma lo to niekt´ore zmienne pozostan
a֒niepodstawione, a je´sli s l´ow b edzie za֒
du˙zo, to ostatnia zmienna otrzyma warto´s´c wielos lowow a.֒
echo Podaj kilka ulubionych imion:
read pierwsze inne
echo Pewnie $pierwsze bardziej Ci sie podoba niz $inne
Uniksowe interpretery polece´n — operacje na zmiennych 19
Zmienne globalne
Nowo utworzone zmienne shella sa֒lokalne dla bie˙z
acej instancji interpretera.֒
Programy i skrypty wywo lywane w czasie pracy nie maj
a֒do nich dost epu.֒
Mo˙zna zmienn
a֒eksportowa´c czyni ac j֒
a֒globaln a:֒
ZMGLOB=20 # zmienna ZMGLOB ma wartosc 20
polec # polecenie nie ma dostepu do zmiennej
export ZMGLOB
polec # teraz polecenie ma dostep do zmiennej
Zmienne mo˙zna tworzy´c w dowolnym momencie. jak r´ownie˙z unicestwia´c poleceniem unset. Istnieje r´ownie˙z posta´c wywo lania polecenia, w kt´orej zmienna jest tworzona i eksportowana tylko na czas wykonywania polecenia:
ZMGLOB2=40 polec # polecenie ma dostep do zmiennej
# ale potem nie ma sladu ani wartosci ani zmiennej
Uniksowe interpretery polece´n — operacje na zmiennych 20
Wi ecej o eksportowaniu zmiennych
֒ Mechanizm”eksportowania”zmiennych jest specyficzny i trzeba dobrze go rozumie´c. Polega on na utworzeniu kopii wszystkich zmiennych eksportowanych, wraz z ich warto´sciami — tzw. ´srodowisko procesu — dla ka˙zdego tworzonego podprocesu. Podproces mo˙ze robi´c ze zmiennymi co zechce, jednak gdy ko´nczy prac
e, ca ly komplet jego zmiennych znika bez ´sladu.֒
export A A=25
sh # wewn. interpreter dziedziczy zmienna
# zmienna A ma wartosc 25 A=50
# teraz A ma wartosc 50 exit
# A ma znow wartosc 25
Jak z tego wynika, operacje na zmiennych mo˙zna wykonywa´c tylko poleceniami wbudowanymi, a nie mo˙zna programami ani skryptami, kt´ore wykonuj
a֒si e֒
w podprocesach. Oczywi´scie, polecenie przypisania warto´sci zmiennej (A=...), i polecenie read musz
a֒by´c poleceniami wbudowanymi shella (dlaczego?).
Uniksowe interpretery polece´n — operacje na zmiennych 21
Podstawowy b l ad
֒ W teorii, eksportowanie ´srodowiska do podprocesu jest prosta֒koncepcj a, kt´or֒
a֒
ka˙zdy mo˙ze zrozumie´c. Cz
esto jednak bywa pope lniany b l֒
ad wed lug schematu:֒
echo Podaj preferowany kolor:
read KOLOR export KOLOR exit
Je´sli powy˙zsze b
edzie wywo lane jako skrypt, to proces wywo luj֒
acy nigdy nie֒
dowie si
e֒jaki jest preferowany kolor u˙zytkownika, nawet je´sli sam wcze´sniej wyeksportowa l powy˙zsze zmienne.
Przypomnijmy, wywo luj
acy proces interpretera polece´n mo˙ze wykona´֒ c taki skrypt bezpo´srednio sam, poleceniem . (kropka). Wtedy wszystko zadzia la jak nale˙zy, zmienna zostanie utworzona z odpowiedni
a֒warto´sci a֒
w procesie wywo luj
acym. Jednak ten spos´ob nie jest og´olnie wygodny. Pozwala֒
tylko na wywo lywanie skrypt´ow (nie program´ow), i tylko gdy interpreter polece´n u˙zytkownika jest dok ladnie tym samym w jakim zosta l napisany skrypt.
Ponadto, skrypty, kt´orych efekty zale˙z
a֒od sposobu wywo lania s a֒myl
ace dla֒
u˙zytkownik´ow.
Uniksowe interpretery polece´n — operacje na zmiennych 22
Przekazywanie warto´sci przez strumienie danych
Rozwa˙zmy ponownie powy˙zszy przyk lad; chcemy napisa´c skrypt kt´ory odpyta u˙zytkownika o preferowany kolor, i przeka˙ze go procesowi nadrzednemu.֒
Pytanie: czy da si
e֒napisa´c skrypt, kt´ory b
edzie w stanie przekaza´c wynik֒
swej pracy do procesu wywo luj acego?֒
Odpowied´z: tak, ale nie przez zmienne tylko przez strumie´n wej´scia/wyj´scia.
Zatem, zamiast eksportowa´c zmienne, powinien on wys la´c otrzymane warto´sci na swoje wyj´scie. Kluczow
a֒kwesti
a֒jest, ˙zeby przypisanie warto´sci zmiennych realizowa l proces macierzysty, bo tylko on ma dost
ep do w la´sciwych zmiennych.֒
KOLOR=‘odpytaj_kolor.sh‘
Pomimo i˙z powy˙zsze przypisanie wygl
ada niewinnie, wymaga nietrywialnej֒
modyfikacji w skrypcie odpytaj_kolor.sh. Przyczyn
a֒jest niejawne skierowanie wyj´scia, wynikaj
ace z mechanizmu zagnie˙zd˙zenia.֒
Uniksowe interpretery polece´n — operacje na zmiennych 23
Skrypt odpytaj_kolor.sh zmodyfikowany na potrzeby przekazania wyniku przez stdout ma nast
epuj֒
ac֒
a֒posta´c:
echo Podaj preferowany kolor: 1>&2 read KOLOR
echo $KOLOR exit
Dialog z u˙zytkownikiem nie mo˙ze ju˙z by´c zrealizowany przez zwyk le polecenie echo, poniewa˙z standardowe wyj´scie skryptu zosta lo przekierowane przez proces wywo luj
acy. W powy˙zszym, wyj´scie stdout polecenia echo zosta lo֒
przekierowane na stderr. Ten strumie´n najcz
e´sciej nie jest nigdzie֒
przekierowywany, aby nie zak l´oca´c raportowania b l
ed´ow (wys lanie zapytania do֒
u˙zytkownika nie zak l´oci ewentualnego komunikatu o b l
edzie jakiego´s polecenia).֒
Zauwa˙zmy, ˙ze powy˙zsze przekierowanie wyj´scia polecenia echo nie zmniejsza jego og´olno´sci. Gdyby proces wywo luj
acy nie przekierowa l mu wyj´scia,֒
zadzia la lby tak samo poprawnie. Przy pisaniu skrypt´ow warto bra´c pod uwag e֒
mo˙zliwo´s´c, ˙ze
”moje” wej´scie lub wyj´scie b
edzie przekierowane. Pisane w ten֒
spos´ob skrypty s
a֒bardzo uniwersalne i daj a֒si
e֒wywo lywa´c na wiele sposob´ow.
Uniksowe interpretery polece´n — operacje na zmiennych 24
Lekkie przegi ecie
֒ Wyobra´zmy sobie, ˙ze chcemy wykona´c jeszcze jedna֒modyfikacj e֒skryptu odpytaj_kolor.shi przekaza´c mu kolor domy´slny, kt´ory zostanie u˙zyty, je´sli u˙zytkownik nie poda swojego (odpowie naci´sni
eciem klawisza ENTER).֒
Pomijamy tu fakt, ˙ze latwo by loby przekaza´c warto´s´c koloru domy´slnego przez argumenty wywo lania (o nich patrz ni˙zej). Za l´o˙zmy jednak, ˙ze z jakiego´s powodu chcemy przekaza´c j
a֒tak jak warto´s´c wynikow
a, przez strumie´n danych.֒
Jak poradzi´c sobie z przekierowanymi obydwoma strumieniami stdin i stdout?
KOLOR=‘echo PINK | odpytaj_kolor.sh‘
Mo˙zna w tym celu wykorzysta´c istniej
acy w systemie plik specjalny terminala,֒
dostepny w katalogu urz֒
adze´n jako /dev/tty.֒
read DOMYSLNY
echo Podaj preferowany kolor \[$DOMYSLNY\]: > /dev/tty
read PREFEROWANY < /dev/tty
if [ -z "$PREFEROWANY" ] then echo $DOMYSLNY else echo $PREFEROWANY fi
Uniksowe interpretery polece´n — operacje na zmiennych 25
Dygresja na temat echa
We wcze´sniejszym przyk ladzie pojawi la sie֒cz
esto stosowana konstrukcja֒
zapytania do u˙zytkownika (tu pomijamy rozwa˙zane poprzednio przekierowania):
echo Podaj preferowany kolor \[$DOMYSLNY\]:
read PREFEROWANY
Polecenie echo domy´slnie dopisuje NEWLINE do wy´swietlanego stringa. Dzi eki֒
temu latwo wy´swietli´c na wyj´sciu pusty wiersz wywo luj
ac echo bez argument´ow.֒
Jednak skutkiem tego w powy˙zszym dialogu jest, ˙ze u˙zytkownik odpowiada w nast
epnym wierszu. Dialog wygl֒
ada lby lepiej, gdyby u˙zytkownik m´og l֒
odpowiedzie´c w wierszu pytania. Dlatego te˙z polecenie echo posiada opcjonaln
a mo˙zliwo´s´֒ c pomijania NEWLINE-a.
Niestety, jest to opcja niestandardowa. Polecenie echo ma wiele wersji — jest i programem wewn
etrznym, i poleceniem wbudowanym wi֒
ekszo´sci֒
interpreter´ow polece´n — i r´o˙zne wersje r´o˙znie implementuj a֒t
e֒opcj e.֒
Historia wersji echa, i r´o˙znic mi
edzy nimi, jest niemal tak stara jak system Unix.֒
Niestety, nie ma dobrej metody przeno´snego wywo lania polecenia echo, je´sli chcemy u˙zy´c jednej z jego opcji. To co nale˙zy zrobi´c?
Uniksowe interpretery polece´n — problemy z echem 26
Zamiast echo mo˙zna u˙zy´ c printf
Je´sli chcemy wy´swietli´c (wys la´c na wyj´scie) komunikat z niestandardowymi opcjami, typowo z pomini
eciem ko´ncowego NEWLINE-a, lepsz֒
a֒mo˙zliwo´sci a֒jest skorzystanie z polecenia printf, kt´ore jest nowsze i bardziej przeno´sne.
printf "Podaj preferowany kolor [%s]: " $DOMYSLNY read PREFEROWANY
Polecenie printf dzia la podobnie do funkcji biblioteki stdio j ezyka C,֒
i podobnie jak ta funkcja nie dopisuje domy´slnie ko´ncowego NEWLINE-a.
Zauwa˙z, ˙ze poni˙zsze wywo lania printf s
a֒r´ownowa˙zne powy˙zszemu:
printf ’Podaj preferowany kolor [%s]: ’ $DOMYSLNY printf "Podaj preferowany kolor [$DOMYSLNY]: "
Uwaga: polecenie printf ma ju˙z w lasn a֒histori
e֒i te˙z mo˙ze powodowa´c problemy z przeno´sno´sci
a֒(o tym poni˙zej). Jednak jego najbardziej podstawowa, przeno´sna funkcjonalno´s´c jest o wiele wi
eksza ni˙z polecenia echo.֒
Uniksowe interpretery polece´n — problemy z echem 27
Jeszcze raz echo
Pomimo i˙z, jak ju˙z wiemy, printf jest zamiennikiem polecenia echo, nie ma powodu nie stosowa´c echo do wy´swietlania zwyk lych komunikat´ow.
Jest jeden szczeg´olny rodzaj komunikat´ow — komunikaty o b l edach.֒
W skryptach te˙z zdarza si
e֒zakomunikowa´c u˙zytkownikowi wyst apienie b l֒
edu.֒
Jednak, gdy skrypt b
edzie wywo lany z przekierowaniem wyj´scia, bo normalnie֒
generuje jakie´s dane, to komunikat nie pojawi si
e֒na wyj´sciu, i u˙zytkownik go nie zobaczy. Co gorsza, zostanie dopisany do strumienia danych, psuj
ac je.֒
Jest to sytuacja podobna do wcze´sniejszej, gdy zapytanie do u˙zytkownika zosta lo przekierowane na stderr. Podobnie komunikaty o b l
edach dobrze֒
jest kierowa´c na stderr (kt´ory zasadniczo do tego s lu˙zy):
echo Skrypt $0: blad, brak wymaganego pliku $filename 1>&2 Zwr´o´cmy uwag
e֒na podanie argumentu 0 (nazwy skryptu) w komunikacie.
W czasie wykonywania skryptu wywo luje si
e֒r´o˙zne programy, a przy u˙zyciu przekierowania (np. potoku) by´c mo˙ze r´ownie˙z wiele skrypt´ow na raz. Bez tej informacji u˙zytkownik mo˙ze nie wiedzie´c, kt´ory skrypt informuje go o b l
edzie.֒
Uniksowe interpretery polece´n — problemy z echem 28
Program line
Program line czyta jeden wiersz z wej´scia stdin, i zwraca go w postaci stringa. To znaczy, wy´swietla na swoim wyj´sciu, to co przeczyta l na wej´sciu.
Dzieki przekierowaniom, i poleceniom zagnie˙zd˙zonym, daje to du˙ze mo˙zliwo´sci.֒
Przyk lad — realizacja dialogu z u˙zytkownikiem:
# za pomoc a read֒
echo Podaj swoj kolor:
read KOLOR
# za pomoca line echo Podaj swoj kolor:
KOLOR=‘line‘
Przyk lad — chcemy otworzy´c plik DANE.TXT i przeczyta´c trzeci wiersz:
# bledne rozwiazanie WIERSZ1=‘line < DANE.TXT‘
WIERSZ2=‘line < DANE.TXT‘
WIERSZ3=‘line < DANE.TXT‘
# poprawne rozwiazanie WIERSZ3=‘(line >/dev/null; \
line >/dev/null; \ line ) < DANE.TXT‘
Uniksowe interpretery polece´n — problemy z echem 29 Uniksowe interpretery polece´n — problemy z echem 30
Argumenty wywo lania skryptu
Skrypt mo˙ze by´c wywo lany z argumentami, podobnie jak ka˙zde polecenie.
Argumenty wpisane w wierszu wywo lania tworz
a֒wektor argument´ow wywo lania. Nazwa skryptu lub programu jest r´ownie˙z elementem tego wektora, traktowanym jako element zerowy:
nazwaskryptu0 arg1 arg2 arg3 ...
Argumenty wywo lania s a֒dost
epne wewn֒
atrz skryptu w uk ladzie pozycyjnym:֒
argument zerowy, nazwa skryptu: $0
pierwszy argument: $1
drugi argument: $2
...
wektor argument´ow bez zerowego, jeden string: $*
wektor argument´ow bez zerowego, oddzielne: $@
Warto´sci argument´ow s
a֒traktowane jako napisy tekstowe, podobnie jak warto´sci zmiennych.
Uniksowe interpretery polece´n — argumenty wywo lania 31
Operacje na wektorze argument´ ow
Wektor argument´ow wywo lania mo˙zna przesuwa´c w lewo operacja shift.֒
Powoduje ona zast
apienie argumentu pierwszego drugim, drugiego trzecim, itp.,֒
efektywnie skracaj
ac wektor argument´ow wywo lania. Argument zerowy (nazwa֒
skryptu) nie podlega przesuwaniu operacj
a shift֒ i pozostaje niezmieniony:
nazwaskryptu0 arg1 arg2 arg3
po shift:
nazwaskryptu0 arg2 arg3
Mo˙zna ustawi´c (nadpisa´c) ca ly wektor argument´ow (od $1) bie˙z acego֒
wywo lania poleceniem set (nowy wektor mo˙ze by´c d lu˙zszy lub kr´otszy):
set jeden dwa trzy
echo $* # wynik: jeden dwa trzy
date # wynik: czw 11 mar 2004 06:45:23
set ‘date‘
echo czas = $5 # wynik: czas = 06:45:23
Uniksowe interpretery polece´n — argumenty wywo lania 32
Inne konstrukcje
” dolarowe”
Interpreter komend posiada szereg dalszych konstrukcji pozwalaj
acych oblicza´c֒
r´o˙zne warto´sci w spos´ob podobny do brania warto´sci argument´ow wywo lania, np.:
numer procesu interpretera polece´n: $$
liczba argument´ow, bez argumentu zerowego: $#
warto´s´c domy´slna, brana gdy danego argumentu brak: ${1:-domysl}
Oraz szereg innych.
R´o˙zne interpretery polece´n definiuj
a֒jeszcze inne, specyficzne konstrukcje dolarowe, dost
epne tylko w danym interpreterze. Na uwag֒
e֒zas luguj a֒jednak konstrukcje zdefiniowane przez standard POSIX, o kt´orych poni˙zej.
Uniksowe interpretery polece´n — argumenty wywo lania 33
Przyk lad: skrypt z argumentami
Argumenty wywo lania przydatne sa֒w wielu sytuacjach. Pozwalaj
a֒np. lepiej zrealizowa´c skrypt odpytania u˙zytkownika o kolor, z poprzednich przyk lad´ow.
Zak ladaj
ac, ˙ze u˙zytkownik podaje kolor domy´slny jako pierwszy argument:֒
DOMYSLNY="$1"
printf "Podaj preferowany kolor [$DOMYSLNY]: " > /dev/tty
read PREFEROWANY < /dev/tty
if [ -z "$PREFEROWANY" ] then echo $DOMYSLNY else echo $PREFEROWANY fi
Pobranie warto´sci domy´slnej z argumentu zamiast wej´scia pozwala latwo zaimplementowa´c sytuacj
e֒braku tego argumentu, i u˙zycie warto´sci wbudowanej:
DOMYSLNY=Pistacjowy
if [ $# -gt 0 ]; then DOMYSLNY=$1; fi
printf "Podaj preferowany kolor [$DOMYSLNY]: " > /dev/tty
read PREFEROWANY < /dev/tty
...
Uniksowe interpretery polece´n — argumenty wywo lania 34
Znaki specjalne: cytowanie string´ ow
\ odbiera znaczenie specjalne nast epuj֒
acego po nim znaku֒
’...’ sztywny string, brak interpretacji wszelkich znak´ow specjalnych
"..." brak interpretacji znak´ow specjalnych z wyj
atkiem $, \, i ‘...‘֒
Ponadto, znak "\" na ko´ncu wiersza ma znaczenie kontynuacji w nast epnym֒
wierszu. Znak NEWLINE (\n, ASCII 10), jest dopuszczalny jako zwyk ly znak wewnatrz napis´ow cytowanych. Traci te˙z swoje znaczenie specjalne po "\".֒
Z lo˙zone wyra˙zenia, z wieloma znakami cytowania, kt´ore mo˙zna czasem napotka´c, s
a֒bardzo trudne do
”rozszyfrowania”. W praktyce, warto pami eta´c֒
nastepuj֒
ac֒
a֒zasad
e: znaki ’...’ trac֒
a֒swoje znaczenie specjalne (staj a֒si
e֒
zwyk lymi znakami), gdy s a֒wewn
atrz stringa "...". I na odwr´ot. Na przyk lad:֒
echo "$PATH" # wartosc zmiennej PATH jest obliczana echo "\$PATH" # nie jest obliczana
echo "\\$PATH" # jest obliczana echo ’$PATH’ # nie jest obliczana echo "’$PATH’" # jest obliczana echo ’"$PATH"’ # nie jest obliczana
Uniksowe interpretery polece´n — znaki cytowania 35 Uniksowe interpretery polece´n — znaki cytowania 36
Status procesu
Ka˙zdy proces generuje kod zako´nczenia (exit code) zwany te˙z statusem zako´nczenia (exit status) lub po prostu statusem. W przypadku skryptu status mo˙zna zwr´oci´c wbudowanym poleceniem exit lub return. Wywo lanie tego polecenia bez argumentu generuje status r´owny 0.
Konwencjonalnie, zerowa warto´s´c statusu oznacza poprawne zako´nczenie procesu, a ka˙zda inna warto´s´c oznacza b l
ad (i cz֒
esto jest kodem b l֒
edu).֒
Programy, kt´orych wynik ma sens logiczny prawdy lub fa lszu (albo sukcesu lub pora˙zki), generuj
a֒zwykle zerowy status w przypadku sukcesu, a niezerowy wpw.
Warto´s´c statusu jest normalnie niewidzialna przy interakcyjnym wykonywaniu polece´n. Jest jednak przechwytywana przez interpreter polece´n, i dla polece´n wykonywanych synchronicznie (w pierwszym planie), bezpo´srednio po wykonaniu polecenia jest dost
epna w zmiennej $?.֒
W przypadku polece´n z lo˙zonych, takich jak: potok, lista, albo skrypt, ich statusem jest status ostatniego wykonanego polecenia.
Uniksowe interpretery polece´n — status i warunki logiczne 37
Wykorzystanie statusu
Wszystkie polecenia generuja֒status, i cz
esto sygnalizuje on pewne fakty, zawsze֒
skrupulatnie opisane w podr
eczniku (man) danego programu/polecenia.֒
Niekt´ore programy s
a֒specjalnie przygotowane do sprawdzania warunk´ow. Za pomoc
a֒statusu raportuj
a֒one jaki´s precyzyjnie zdefiniowany warunek, i czasem maja֒opcj
e֒powoduj ac֒
a֒brak wy´swietlania czegokolwiek na wyj´sciu.
Przyk ladami takich program´ow s
a: grep, cmp, mail, i inne. Generowany status֒
mo˙zna latwo wykorzysta´c, za pomoc
a֒warunkowych list polece´n || i &&.
Na przyk lad, program ls generuje niezerowy status, gdy napotka jaki´s b l ad,֒
zwykle brak pliku o podanej nazwie.
ls jakis_plik > /dev/null 2>&1 && echo Jest jakis_plik.
ls jakis_plik > /dev/null 2>&1 || echo Nie ma jakis_plik.
Przekierowanie wyj´s´c stdout i stderr na /dev/null ma na celu wyeliminowanie wszelkich komunikat´ow od programu ls, kt´ory jest tutaj wykorzystywany tylko jako tester istnienia okre´slonego pliku.
(test -e jakis_plik && echo Istnieje.) || echo Nie istnieje.
Uniksowe interpretery polece´n — status i warunki logiczne 38
Polecenie warunkowe if
”Etatowym” poleceniem warunkowym system´ow uniksowych jest if o sk ladni:
if test -r prog.dan then
prog < prog.dan else
prog fi
Zauwa˙zmy, ˙ze wewn
etrzne wywo lanie polecenia test mo˙zna zast֒
api´c wywo laniem֒
dowolnego innego programu lub polecenia wbudowanego. If wykonuje je, podobnie jak wykonywane s
a֒polecenia zagnie˙zd˙zone, i sprawdza jego status.
Zapis polecenia if cz
esto skraca si֒
e֒pomijaj
ac NEWLINE po s lowach֒
kluczowych: then, else, i fi. W pozycjach polecenia if, gdzie znajduj a֒si
e֒
polecenia wewn
etrzne, mo˙zna pomin֒
a´c֒ NEWLINE jedynie pod warunkiem zastapienia go ´srednikiem:֒
if [ -r prog.dan ] ; then prog < prog.dan ; else prog ; fi
Uniksowe interpretery polece´n — status i warunki logiczne 39
Testowanie warunk´ ow programem test
”Etatowym” narz
edziem do sprawdzania warunk´ow jest test, obs luguj֒
acy֒
bogaty j
ezyk specyfikacji warunk´ow.֒
Przyk lady:
test -r filespec # czy plik istnieje i jest dost.do odczytu test -d filespec # czy plik istnieje i jest katalogiem test -z string # czy dany string ma dlugosc zero test string # czy dany string jest pusty
test str1 = str2 # czy dane dwa stringi sa identyczne test n1 -eq n2 # czy dwie liczby calkowite rowne test 1.1 -eq 1 # daje 0 (prawda) - przez zaokraglenie test 1+1 -eq 2 # daje 1 (falsz) - nie oblicza wyrazen test n1 -ge n2 # czy n1 >= n2, analogicznie -gt -le -lt Jak wida´c, program test wykonuje pewne operacje liczbowe, np. zaokr
aglanie,֒
ale nie wykonuje oblicze´n arytmetycznych.
Uniksowe interpretery polece´n — status i warunki logiczne 40
Skr´ ocona forma wywo lania test
Polecenie test jest niejednoznaczne — jest zar´owno poleceniem wbudowanym wielu interpreter´ow polece´n, jak i programem zewn
etrznym na wszystkich֒
systemach uniksowych. Te warianty nieco r´o˙zni a֒si
e֒od siebie. Zauwa˙zmy, ˙ze mo˙zemy zawsze wymusi´c wykonanie programu zewn
etrznego wywo laniem:֒
/usr/bin/test 1.1 -eq 1 && echo /usr/bin/test zaokragla Istnieje forma skr´ocona wywo lania polecenia test, kt´ora zawsze wywo luje jego forme֒wbudowan
a֒w interpreter polece´n:
[ 1.1 -eq 1 ] && echo Wbudowany test zaokragla W przypadku u˙zycia polecenia if wywo lanie to ma posta´c
if [ 1.1 -eq 1 ] ; then echo Wbudowany test zaokragla; fi Nawias kwadratowy jest w skr´oconej formie jakby zamiennikiem s lowa
”test”
i musi po nim wyst
api´֒ c spacja aby zosta l poprawnie zinterpretowany.
Uniksowe interpretery polece´n — status i warunki logiczne 41
Problemy ze skr´ ocon a form
֒a wywo lania test
֒ Skr´ocona forma wywo lania test w poleceniu if budzi pewne nieporozumienia, bo sprawia wra˙zenie, ˙ze jest to pewna forma sk ladniowa polecenia if.Stad cz֒
esto pisane s֒
a֒b l
edne wywo lania typu:֒
if [ $LOOPS=6 ] ; then ... fi if [$LOOPS = 6] ; then ... fi if [ $LOOPS = 6 ] ; then ... fi Pierwsza forma jest typowym b l
edem pocz֒
atkuj֒
acych, niestety niemo˙zliwym do֒
wykrycia. Polecenie test sprawdza wtedy niepusto´s´c danego stringa (np. 0=6) i odpowiada twierdz
aco, a u˙zytkownik nie widzi gdzie tkwi problem.֒
Druga forma jest b l
edna sk ladniowo, ale niestety, normalnie b l֒
ad w skrypcie֒
nie powoduje zatrzymania ca lego skryptu. Pojawia si
e֒komunikat o b l
edzie, ale reszta skryptu si֒
e֒wykonuje. Pocz atkuj֒
acy u˙zytkownicy maj֒
a֒
tendencj
e֒do ignorowania niezrozumia lych komunikat´ow, i akceptowania wyniku.
Trzecia forma zasadniczo nie zawiera b l edu. B l֒
ad jednak si֒
e֒objawi, je´sli zmienna LOOPS nie b
edzie mia la warto´sci (lub b֒
edzie pustym stringiem). Po֒
interpretacji nie zostanie po niej ˙zaden ´slad, i wyra˙zenie b edzie b l֒
edne [ = 6 ]֒
Uniksowe interpretery polece´n — status i warunki logiczne 42
Skr´ ocona forma test — wniosek
Analiza b lednych przyk lad´ow skr´oconego wywo lania test, i do´swiadcze´n z du˙z֒
a֒
liczb a֒b l
ednych skrypt´ow, prowadz֒
a֒do nast epuj֒
acego zalecenia i wniosku:֒
Zalecenie: stosuj pe ln a form֒
e test zamiast skr´֒ oconej!!
Zwraca to wi eksz֒
a֒uwag
e֒na to co jest wywo lywane, i gdzie szuka´c b l edu.֒
if [ $LOOPS=6 ] ; then ... fi if [$LOOPS = 6] ; then ... fi if [ $LOOPS = 6 ] ; then ... fi if test "$LOOPS" = 6 ; then ... fi Zauwa˙zmy, stosuj
ac ostatni֒
a֒form
e, kompletnie unikamy b l֒
edu z formy drugiej.֒
Latwiej te˙z spostrzec b l
ad z formy pierwszej. Pisz֒
ac wiele wywo la´n polecenia֒
test latwiej skojarzy´c, ˙ze wyra˙zenie $LOOPS=6 nie jest podobne do typowych,
”rozstrzelonych” wyra˙ze´n polecenia test.
Natomiast aby unikn a´c֒ b l
ed´ow z formy trzeciej, warto nabra´c nawyku pisania֒
warto´sci zmiennej w cudzys lowach. Z wyj
atkiem rzadkich przypadk´ow, kiedy֒
zale˙zy nam na efekcie
”rozp lyni ecia” si֒
e֒zmiennej, gdy jej warto´s´c jest pusta, taki spos´ob zawsze jest poprawny i bezpieczny.
Uniksowe interpretery polece´n — status i warunki logiczne 43
Polecenie warunkowe case
Polecenie case jest innym rodzajem polecenia warunkowego, ale nie sterowanego warunkami logicznymi, tylko warto´scia֒wyra˙zenia:
case ‘uname -s‘ in
"Linux") PATH=$PATH:~/Bin.Linux ;;
"SunOS") PATH=$PATH:~/Bin.SunOS ;;
*) echo Unknown system, PATH unchanged. ;;
esac
Poza do´s´c specyficzn a֒sk ladni
a, to polecenie nie wyr´o˙znia si֒
e֒niczym szczeg´olnym.
Uniksowe interpretery polece´n — status i warunki logiczne 44
P etla logiczna while
֒ Istnieje polecenie while realizujace p֒
etl֒
e֒sterowan
a֒warunkiem logicznym.
Zasada dzia lania jest podobna do polecenia if, tylko warunek jest obliczany, i jego status sprawdzany, ka˙zdorazowo przed wej´sciem do p
etli.֒
Przyk lad — wykonanie p
etli n razy, gdzie n jest warto´sci֒
a֒zmiennej NLOOPS:
i=0
while test $i -lt $NLOOPS do
echo Tu jakies obliczenia i=$i ...
i=‘echo $i 1 + p | dc‘
done
Do inkrementacji zmiennej i zosta l tu wykorzystany tradycyjnie kalkulator RPN o nazwie dc, poniewa˙z historycznie intrepretery polece´n system´ow uniksowych nie maj
a֒zdolno´sci oblicze´n arytmetycznych. Takie wyra˙zenia zosta ly wprowadzone rozszerzeniami standardu POSIX, i b
ed֒
a֒om´owione poni˙zej.
Uniksowe interpretery polece´n — polecenia petli֒ 45
P etla wyliczeniowa for
֒Standardowe interpretery polece´n system´ow uniksowych nie posiadaj a֒p
etli֒
arytmetycznej w stylu for (i=0;i<N;++i). Posiadaj
a֒natomiast polecenie for, kt´ore realizuje p
etl֒
e֒wyliczeniow
a, wykonuj֒
ac֒
a֒swoj
a֒tre´s´c kolejno dla wszystkich s l´ow (string´ow) podanych w wywo laniu.
Czestym zastosowaniem tego polecenia jest, w po l֒
aczeniu z mechanizmem֒
globbingu, wykonanie pewnych polece´n dla wszystkich zadanych plik´ow, np.:
for x in *.c do
if test ! -e ${x}~
then echo Nie istnieje starsza wersja pliku $x
# teraz wiemy, ze starsza wersja istnieje, porownujemy
# cmp -s nic nie wyswietla, status informuje o roznicach elif cmp -s ${x}~ ${x}
then echo Istnieje starsza IDENTYCZNA wersja pliku $x else echo Istnieje starsza wersja pliku $x
fi done
Uniksowe interpretery polece´n — polecenia petli֒ 46
Funkcje interpretera polece´ n
ask_yes_no() {answer=X while true do
echo The question: $1 echo Answer yes or no:
read answer case $answer in
yes|Yes|YES) return 0;;
no|No|NO) return 1;;
esac
echo Wrong answer.
echo ""
done }
# przyklad wywolania:
if ask_yes_no "Czy kasowac\
pliki tymczasowe?"
then
rm -f *.o a.out fi
Mo˙zna r´ownie˙z przechwyci´c dane wy´swietlane przez funkcj
e֒na wyj´sciu, jednak wtedy np. konwersacja z u˙zytkownikiem musia laby odbywa´c si
e֒przez stderr.
Uniksowe interpretery polece´n — inne mechanizmy 47
Parametry opcjonalne interpretera polece´ n
Interpreter posiada opcjonalne argumenty wywo lania (flagi), kt´ore w wektorze argument´ow nie licza֒si
e֒jako argumenty pozycyjne $1, $2, . . . . Mo˙zna je poda´c w wywo laniu skryptu, albo ustawi´c w czasie pracy poleceniem set, np. set -f:
-v powoduje wy´swietlenie wczytanych linii polecenia
-x powoduje wy´swietlenie polece´n przed wykonaniem, po interpretacji -n powoduje tylko wy´swietlanie polece´n do wykonania, bez wykonania -e powoduje zatrzymanie interpretera z b l
edem je´sli jakiekolwiek polecenie֒
zwr´oci niezerowy status -u powoduje wygenerowanie b l
edu przy pr´obie u˙zycia niepodstawionej zmiennej֒
-f powoduje wy l
aczenie dopasowania nazw plik´ow do znak´ow specjalnych֒
takich jak ∗
Niezale˙znie od ustawienia flagi -u dost
epna jest konstrukcja ${zm?} generuj֒
aca֒
b lad (status 1) gdy zmienna zm jest niepodstawiona.֒
Po ustawieniu danej flagi, mo˙zna j
a֒ponownie wy l
aczy´c zamieniaj֒
ac minus na֒
plus, np. set +f ponownie w l
acza mechanizm dopasowania nazw plik´ow.֒
Uniksowe interpretery polece´n — inne mechanizmy 48
Magia #!
Wiekszo´s´c wsp´o lczesnych interpreter´ow polece´n stosuje konwencj֒
e֒polegaj ac֒
a֒
na specjalnym traktowaniu skrypt´ow, kt´orych pierwsze dwa bajty to #!
(fachowa wymowa angloj
ezyczna: sha-bang). Do wykonania takich skrypt´ow֒
interpreter wywo luje program okre´slony w pierwszym wierszu skryptu, po #!.
Dalszy ci
ag wiersza traktowany jest jako wektor argument´֒ ow wywo lania.
Zwr´o´cmy jednak uwag
e, ˙ze ten wektor nie jest interpretowany, jak typowy֒
wiersz polecenia, tylko brany dos lownie. Nie ma wyszukiwania wed lug zmiennej PATH, zatem pierwszy argument musi by´c ´scie˙zk
a pliku (pe ln֒
a/bezwzgl֒
edn֒
a,֒
lub wzgl edn֒
a). Mo˙zna zada´c argumenty dla programu, ale nie mo˙zna stosowa´c֒
˙zadnych mechanizm´ow shella: zmiennych, skierowa´n, zagnie˙zd˙ze´n, itp.
Te mechanizm pozwala pisa´c skrypty dla j
ezyk´ow interpretowanych, kt´orych֒
interpreter jest dost
epny w systemie i wywo lywalny jako program.֒
#!/usr/bin/perl
use Config qw(myconfig);
print myconfig();
Uniksowe interpretery polece´n — inne mechanizmy 49
Mechanizm #! — uwagi
Mechanizm #! bywa czesto nadu˙zywany. Zauwa˙zmy, ˙ze zwyk le skrypty֒
interpretera polece´n mog
a֒by´c wywo lane przez nazw
e֒pliku (je´sli plik posiada atrybut
”x”), i zostan
a֒zwykle poprawnie wykonane przez standardowy shell uniksowy.
Mechanizm #! wymusza wywo lanie konkretnego programu, z konkretnego pliku, z konkretnymi argumentami. Je´sli na tym nam zale˙zy, trzeba go u˙zy´c.
Natomiast w pozosta lych przypadkach, wi eksz֒
a֒przeno´sno´s´c uzyskujemy, pomijaj
ac wiersz #!. W og´olno´sci, pisz֒
ac skrypt nie mamy pewno´sci czy֒
konkretny interpreter b edzie dost֒
epny w danym systemie, oraz jaka dok ladnie֒
jest jego ´scie˙zka pliku.
Bezmy´slne wklejanie konstrukcji #! w ka˙zdym skrypcie ´swiadczy o niekompetencji programisty.
Uniksowe interpretery polece´n — inne mechanizmy 50
Uniksowe interpretery polece´ n — historia
• Oryginalny interpreter polece´n: Bourne shell (/bin/sh)
• Zmodyfikowany interpreter polece´n do pracy interakcyjnej: C-shell (/bin/csh) zawiera dodatkowe mechanizmy do pracy interakcyjnej, lecz r´ownie˙z zmienion
a֒sk ladni
e֒polece´n z lo˙zonych. Powsta l paradygmat pisania skrypt´ow Bourne shella, i pracy interakcyjnej w C-shellu.
• P´o´zniej, w miar
e֒rozwoju system´ow uniksowych pojawi lo si
e֒wiele wersji interpreter´ow polece´n. Typowo zawiera ly coraz wi
ecej mechanizm´ow do֒
pracy interakcyjnej, jak r´ownie˙z konstrukcji programistycznych.
Te programy wpisywa ly si e֒w grup
e֒kompatybiln
a֒z oryginalnym interpreterem Bourne’a, albo w grup
e֒kompatybiln
a֒z C-shellem.
Jednym z najbardziej rozbudowanych w grupie Bourne shella jest bash (Bourne Again Shell) na opensource owej licencji Gnu, wprowadzaj
acy bardzo֒
du˙zo rozszerze´n, w tym szereg mechanizm´ow z grupy C-shella.
• Specyfikacja POSIX interpretera polece´n: wprowadzi la standard shella zasadniczo zgodny z Bourne shellem, z szeregiem rozszerze´n.
Uniksowe interpretery polece´n — por´ownanie interpreter´ow 51
Uniksowe interpretery polece´ n — praktyka
• Wsp´o lcze´snie u˙zywane interpretery (tcsh, ksh, zsh, i bash) r´o˙zni a֒si
e֒
minimalnie, g l´ownie sk ladni
a֒polece´n programowych (warunkowych i p etli).֒
W pracy interakcyjnej, gdzie te polecenia wykorzystuje si
e֒rzadko, mo˙zna nie zorientowa´c si
e֒nawet jakiego interpretera w danej chwili u˙zywamy.
• Z punktu widzenia maksymalnej kompatybilno´sci pisanych skrypt´ow, i przeno´sno´sci na najwi
eksz֒
a֒liczb
e֒system´ow uniksowych, nale˙zy bra´c pod uwage֒oryginalny Bourne shell. Nie oznacza to rezygnacji z jakich´s wa˙znych funkcji, a jedynie konieczno´s´c pisania pewnych mniej wygodnych konstrukcji.
• Pisz
ac skrypty pod k֒
atem ich przeno´sno´sci dla system´ow wsp´o lczesnych,֒
warto bra´c pod uwag
e֒standard POSIX i u˙zywa´c konstrukcji dobrze zdefiniowanych przez ten standard.
• Mechanizm #! powinien by´c zarezerwowany dla skrypt´ow napisanych pod katem konkretnego interpretera (lub wersji), wykorzystuj֒
acego jego֒
specyficzne konstrukcje. Mechanizm ten nie wynajdzie nam
”lepszego”
interpretera, gdy np. nie mamy pewno´sci czy standardowy interpreter systemu poprawnie wykona rozszerzone konstrukcje POSIX.
Uniksowe interpretery polece´n — por´ownanie interpreter´ow 52
Uwagi na temat basha
• bash jest bardzo rozbudowanym uniksowym interpreterem polece´n, zgodnym ze standardem POSIX. Jest produktem typu
”open source” na licencji Gnu, i jest z regu ly instalowany na systemach linuksowych, oraz na wielu systemach uniksowych, jako interpreter u˙zytkownika (ale nie systemowy).
• W ten spos´ob bash szybko staje si
e֒najpopularniejszym [ ¨⌣] i czasami wrecz֒ jedynym [ ¨⌢] shellem.
• Jednak bash posiada szereg rozszerze´n wykraczaj
acych poza standard֒
POSIX. Do tego istnieje niezliczona liczba podr
ecznik´ow typu֒
”Programowanie w bashu”, oraz
”Kruczki i sztuczki basha”, intensywnie eksploatuj
acych te rozszerzenia. Powoduje to tendencj֒
e֒do pisania skrypt´ow typu bash-only, cz
esto zupe lnie niezamierzenie i niepotrzebnie.֒
• W rzeczywisto´sci bash nie jest jedynym interpreterem, i nie mo˙zna zak lada´c ani ˙ze jest interpreterem u˙zytkownika, ani systemowym (tzn. wykonuj
acym֒
skrypty administracyjne), ani ˙ze w og´ole jest zainstalowany na danym systemie. Skrypty odwo luj
ace si֒
e֒do basha (wywo luj
ac go jawnie, lub przez֒
mechanizm #!), albo wykorzystuj
ace jego specyficzne konstrukcje, nie b֒
ed֒
a֒
dzia la´c we wszystkich ´srodowiskach uniksowych.
Uniksowe interpretery polece´n — por´ownanie interpreter´ow 53
Przyk lad: nieprzeno´sne konstrukcje
Jako przyk lad zagadnienia przeno´sno´sci, rozwa˙zmy polecenie printf, w miar e֒
przeno´snie pozwalaj
ace tworzy´c w skryptach napisy niezako´nczone znakiem֒
NEWLINE. Za l´o˙zmy, ˙ze chcemy utworzony napis przypisa´c do zmiennej MSG:
MSG=‘printf "Przykladowy komunikat: "‘
To polecenie zostanie poprawnie wykonane w ka˙zdym interpreterze (grupy Bourne shella), poniewa˙z korzysta tylko z mechanizmu zagnie˙zd˙zenia, i instrukcji przypisania. Wywo lane zostanie wbudowane polecenie printf, je´sli interpreter takie posiada, lub program zewn
etrzny, je´sli tylko istnieje w systemie.֒
Dla por´ownania, bash ma wbudowane polecenie printf, z niestandardow a֒
opcja -v֒ powoduj ac֒
a֒od razu przypisanie stringa zmiennej (˙zaden program nie mo˙ze obs lugiwa´c takiej formy, z powod´ow, kt´ore zosta ly wcze´sniej wyja´snione):
printf -v MSG "Przykladowy komunikat: "
Powy˙zsze wywo lanie zadzia la tylko w bashu. Nie wykonaj
a֒go poprawnie: sh, ksh, dash, zsh, i zapewne wiele innych. Niekt´ore z nich posiadaj
a֒wbudowane polecenie printf, ale ˙zadne nie obs luguje argumentu -v.
Uniksowe interpretery polece´n — por´ownanie interpreter´ow 54
POSIX shell: obliczanie warto´sci zmiennych
W Bourne shellu, poza podstawowa֒postaci
a֒odwo lania si
e֒do warto´sci zmiennej
$var, albo jej og´olniejsz a֒postaci
a ${var}֒ istnieje szereg dodatkowych postaci sk ladniowych uruchamiaj
acych dodatkowe funkcjonalno´sci:֒
${var:-default} u˙zyj warto´sci domy´slnej je´sli nie ma warto´sci lub null
${var:=default} u˙zyj warto´sci domy´slnej j.w. i jednocze´snie podstaw zmienn
a֒(nie mo˙zna w ten spos´ob podstawi´c parame- tr´ow pozycyjnych)
${var:?msg} u˙zyj warto´sci zmiennej je´sli istnieje i jest non-null, w.p.w. wy´swietl komunikat i zako´ncz skrypt z b l
edem֒
Standard POSIX dodatkowo wprowadzi l kilka dalszych podobnych konstrukcji:
${zm:+value} u˙zyj podanej warto´sci je´sli zmienna mia la ju˙z warto´s´c non-null
${#zm} oblicz d lugo´s´c warto´sci (stringa)
${zm%suf} usu´n najkr´otszy przyrostek
${zm%%suf} usu´n najd lu˙zszy przyrostek
${zm#pref} usu´n najkr´otszy przedrostek
${zm##pref} usu´n najd lu˙zszy przedrostek
Uniksowe interpretery polece´n — konstrukcje POSIXowe 55
POSIX shell: polecenia zagnie˙zd˙zone
POSIX wprowadzi l alternatywna֒notacj
e֒dla polece´n zagnie˙zd˙zonych:
$(polecenie)
co jest r´ownowa˙zne tradycyjnej sk ladni polece´n zagnie˙zd˙zonych Bourne shella:
‘polecenie‘
Alternatywna sk ladnia pozwala w sensowny spos´ob zagnie˙zd˙za´c w sobie wiele polece´n, co w oryginalnym Bourne shellu wymaga lo karko lomnej ekwilibrystyki.
Uniksowe interpretery polece´n — konstrukcje POSIXowe 56
POSIX shell: operatory arytmetyczne
Interpretery polece´n zgodne ze standardem POSIX realizuja֒szereg dodatkowych operacji, kt´ore u latwiaj
a֒pisanie skrypt´ow. Nale˙z
a֒do nich np. operatory arytmetyczne:
echo 2+2= $((2+2))
W wyra˙zeniach arytmetycznych zapisywanych w podw´ojnych nawiasach trzeba uwa˙za´c na operatory por´ownania, poniewa˙z zwracaj
a֒one warto´sci zgodne z konwencj
a֒j
ezyk´ow takich jak C, czyli prawda jest reprezentowana przez֒
1 a fa lsz przez 0, odwrotnie ni˙z w konwencji warto´sci logicznych interpretowanych przez status polecenia.
echo ’3>2?’ $((3>2))
Uniksowe interpretery polece´n — konstrukcje POSIXowe 57
POSIX shell: operatory arytmetyczne (cd.)
Standard POSIX pozostawia jednak pewna֒dowolno´s´c w implementacji operator´ow arytmetycznych, np. nie wymaga implementacji operator´ow -- ani ++. Niekt´ore interpretery je implementuj
a, ale niestety, powoduje to֒
dwuznaczno´s´c interpretacji pewnych wyra˙ze´n:
$ bash -c ’b=5; echo $((--b)); echo $((--b))’
4 3
$ zsh -c ’b=5; echo $((--b)); echo $((--b))’
4 3
$ ksh -c ’b=5; echo $((--b)); echo $((--b))’
5 5
$ dash -c ’b=5; echo $((--b)); echo $((--b))’
5 5
W tym przypadku dash i ksh zinterpretowa ly podw´ojny minus jako podw´ojne przeczenie i obliczy ly poprawny wynik.
Uniksowe interpretery polece´n — konstrukcje POSIXowe 58
POSIX shell: dopasowanie nazw plik´ ow
Standard POSIX rozszerzy l mechanizm globbing dopasowania metaznak´ow*, ?, [...]do nazw plik´ow o klasy znak´ow za pomoc
a֒wyra˙zenia [[:klasa:]], z nast
epuj֒
acymi klasami znak´ow:֒
• [:digit:]
• [:alpha:]
• [:lower:]
• [:upper:]
• [:punct:]
Na przyk lad, dopasowanie plik´ow o nazwach, kt´orych cz
e´s´c֒ podstawowa ko´nczy sie֒cyfr
a, i posiadaj֒
acych tryliterowe rozszerzenia:֒
*[[:digit:]].[[:alpha:]][[:alpha:]][[:alpha:]]
Zauwa˙zmy, ˙ze korzystanie z tych konstrukcji zawsze wymaga pisania podw´ojnych nawias´ow kwadratowych.
Uniksowe interpretery polece´n — konstrukcje POSIXowe 59
POSIX shell: lokalizacja
LANG — domy´slna warto´s´c lokalizacji, dzia la w braku zmiennych LC * LC COLLATE — schemat porz
adkowania napis´ow znakowych֒
LC CTYPE — schemat typ´ow znakowych LC MESSAGES — format i j
ezyk komunikat´ow֒
LC NUMERIC — zestaw konwencji prezentacji warto´sci liczbowych LC TIME — zestaw konwencji formatowania daty i czasu LC MONETARY — format pieni
e˙zny֒
LC PAPER — rozmiar papieru
LC NAME — format prezentacji nazw (i nazwisk) LC ADDRESS — format prezentacji adresu i lokalizacji LC TELEPHONE — format prezentacji numer´ow telefonicznych LC MEASUREMENT — stosowane konwencje miar (np. metryczna) LC ALL — warto´s´c przes laniaj
aca wszystkie pozosta le zmienne LC *֒
Uniksowe interpretery polece´n — konstrukcje POSIXowe 60