Úvod do systémového programování a Linux/UNIX systému
Obsah prezentace Proč studujeme OS Nástroje a vývojové UNIX prostředky Linux Hlavičkové soubory Distribuce Knihovny GNU projekt, FSF Statické Sdílené Programování v Linuxu Filozofie OS UNIX Unixové programy Základní příkazy Kompilátor jazyka C
Filip Malý KIKM FIM UHK
2
Proč studujeme operační systémy Jedná se o nejrozsáhlejší a nejsložitější systémy Uplatňují se v nich mnohé vědecké poznatky Softwarové inženýrství Struktury dat Sítě Algoritmy … Čas od času je potřeba operační systém upravit, pak je ovšem potřeba jim rozumět Pro psaní ovladačů … Techniky tvorby operačních systémů lze uplatnit i v jiných oblastech Filip Malý KIKM FIM UHK
3
UNIX Vyvinut Bell Laboratories, kdysi součást AT&T Navržen v roce 1970 pro firmu Digital Equipment PDP Víceuživatelský systém pro širokou řadu HW platforem (od PC přes víceCPU servery až po superpočítače) Ochranná známka spravovaná specifikací X/Open a vztahuje se na OS vyhovující specifikaci X/Open XPG4.2 (SPEC1170) Definuje názvy rozhraní, chování všech funkcí OS Je do značné míry sjednocení dřívějších specifikací, P1003 nebo POSIX aktivně vyvíjená ústavem IEEE (Institute of Electrical and Electronic Engineers)
Filip Malý KIKM FIM UHK
4
Mnoho UNIXů Komerční Solaris (Sun) pro SPARC a Intel …
Volné FreeBSD Linux …
Filip Malý KIKM FIM UHK
5
Linux
1983 – Richard Stallman oznamuje začátek projektu GNU (GNU is Not Unix – rekurzivní akronym) 1984 – odchází z MIT, má povolení používat zařízení AI laboratoře, vytváří GNU C Compiler – GCC a GNU Emacs, SW je free = svobodný 1985 – vzniká Free Software Foundation – FSF, pro GNU 1987 – Andrew Tanenbaum MINIX 1.0, 4.77MHz, 256KB RAM, 360KB pružný disk 1991 – Linus Torvald – přenáší na 386PC GCC a BASH (Bourne Again Shell), GNU nemá OS (HURD, Mach) Volně šiřitelná implementace unixového jádra Inspirovaný OS UNIX, proto podobné problémy = většina programů pro UNIX lze přeložit a spustit pod Linuxem včetně komerčních aplikací prodávaných pro UNIXy Linus Torvalds Univerzita Helsinky (inspirace systémem Minix = „malý Unix“) Nepoužívá kód AT&T ani žádný jiný patentovaný kód
Filip Malý KIKM FIM UHK
6
Distribuce, GNU projekt a FSF (Free Software Foundation) Linux = jádro OS Linux + programovací nástroje + utility a nástroje + aplikační SW = distribuce GNU/Linuxu Slackware, SuSE, Debian, Red Hat, Turbo Linux, Ubuntu, … Richard Stallman – zakladatel FSF, autor GNU Emacs, iniciátor projektu GNU Projekt GNU = pokus o vytvoření operačního systému a vývojového prostředí plně kompatibilní s OS UNIX Filip Malý KIKM FIM UHK
7
Programování Linuxu „Programování v UNIXu znamená používání jazyka C“ UNIX původně vytvořen v C včetně velkého množství aplikací, ale k dispozici není jen C
K dispozici celá řada jazyků Ada, Eiffel, Icon, Lisp, Perl, Python, SQL, C, C++, Forth, Java, Modula 2, Objective C, PostScript, Scheme, Tcl/Tk, Fortran, JavaScript, Modula 3, Pascal, Prolog, Smalltalk, UNIX Bourne Shell, … Filip Malý KIKM FIM UHK
8
UNIXové programy
Dva typy
Spustitelné soubory a skripty
Něco jako exe na Windows
Odpovídají dosovým souborům bat
Spouští za nás aplikace (obdoba jako command.com v MS Dosu), které vyhledává v zadané sadě cest uložených v proměnné PATH /bin, /usr/bin, /usr/local/bin, pro správce aplikace pro správu systému v /usr/sbin Volitelné komponenty OS obvykle do /opt Ukázka PATH (bez „“): /usr/local/bin:/bin:.:/usr/bin
Spustitelné soubory
Skripty = kolekce instrukcí, kterými se řídí jiný program, interpret Na uživatelské úrovni není mezi nimi žádný rozdíl, lze zaměnit skript přeloženým programem a naopak Shell – komunikujeme s ním od přihlášení do systému
oddělovačem dvojtečka (UNIX byl první, kdo definoval :, až po Filip s Malý 9 něm přišel MS-Dos ;) KIKM FIM UHK
Kompilátor jazyka C #include <stdio.h> int main() { printf(“Ahoj!\n“); return 0; } GNU překladač C = gcc Jak přeložit a spustit program Přeložíme: $ gcc -o pozdrav pozdrav.c Spustíme: $ ./pozdrav (./ znamená, aby shell spustil program z daného umístění) Volba -o specifikuje název výsledného přeloženého souboru (pokud nebude uvedena, pak vytvoří tzv. assembler output a.out) Filip Malý KIKM FIM UHK
10
Nástroje a vývojové prostředky (Linux) 1 Programy součástí systému a pro obecné použití /usr/bin Programy instalované pro specifický stroj nebo lokální síť /usr/local/bin Doplňkové aplikace a programové systémy své vlastní adresářové struktury, například /usr/X11 gcc obvykle v /usr/bin nebo /usr/local/bin Dále spouští různé podpůrné programy, jejich umístění specifikováno při kompilaci překladače a obvykle se liší dle typu hostitele, obvykle však Filip Malý KIKM FIM UHK 11 /usr/lib/gcc-lib
Nástroje a vývojové prostředky 2 Hlavičkové soubory Obsahují definice konstant a deklarace volání systémových a knihovních funkcí Pro C obvykle /usr/include Pokud jsou závislé na konkrétní podobě OS, pak obvykle /usr/include/sys nebo /usr/include/linux Další možné: /usr/include/X11 ( pro X Window), /usr/include/g++-2 (pro GNU C++) Jak zpřístupnit hlavičkové soubory na nestandardních místech $ gcc -I/usr/neco/include pozdrav.c Filip Malý KIKM FIM UHK
12
Nástroje a vývojové prostředky 3
Knihovny
„Sbírky“ předkompilovaných funkcí, znovupoužitelnost Sady příbuzných funkcí – obrazovka curses, databáze dbm, … Obvykle uloženy v /lib, /usr/lib Linker implicitně prohledává jen standardní knihovnu (pozůstatek z doby pomalých počítačů a drahého strojového času)
Obvykle knihovny existují jako statické i jako sdílené
Knihovny musí dodržovat stanovené konvence a je třeba je uvést na příkazovém řádku libX.YZ, kde X je programovací jazyk a YZ typ knihovny (a = tradiční statická a so nebo sa sdílená knihovna), například libc.a značí tradiční statickou knihovnu jazyka C $ gcc -o pozdrav pozdrav.c /usr/lib/libm.a nebo $ gcc -o pozdrav pozdrav.c -lm kde -lm je zkrácený zápis pro knihovnu libm.a (pokud bude nalezena sdílená knihovna, bude upřednostněna před statickou)
$ gcc -o pozdrav -L/usr/neco/lib pozdrav.c -lX11 přeloží a sestaví program pozdrav s použitím knihovny libX11, která se nachází v adresáři /usr/neco/lib Filip Malý KIKM FIM UHK
13
Nástroje a vývojové prostředky 4 Statické knihovny Říká se jim archívy a udržují se aplikací ar Tradičně mají koncovku .a Například /usr/lib/libc.a, /usr/X11/lib/libX11.a Pokud program potřebuje nějakou funkci v takové knihovně, musí obsahovat odkaz na hlavičkový soubor, který danou funkci deklaruje – překladač a linker se postarají o zkombinování kódu programu a knihovny do jednoho spustitelného programu
Chceme-li použít jinou než standardní knihovnu C, sdělíme to překladači Malý KIKM„L“) FIM UHK přepínačem –l Filip (malé
14
Nástroje a vývojové prostředky 5
Příklad
#include <stdio.h> void pozdrav1(int arg) { printf("toto je volani pozdrav1: %d\n", arg); }
#include <stdio.h> void pozdrav2(char *arg) { printf("toto je volani pozdrav2: %s\n", arg); }
Filip Malý KIKM FIM UHK
15
Nástroje a vývojové prostředky 6
Každá funkce do samostatného souboru, následně uložíme a přeložíme, tím získáme objektové soubory, které můžeme zařadit do knihovny $ gcc -c pozdrav1.c pozdrav2.c Pokud bychom -c neuvedli, překladač by se snažil sestavit kompletní program, což by selhalo (nedefinovali jsme totiž funkci main) Vytvoří se soubory s koncovkou .o Nyní napíšeme program, který bude volat funkci pozdrav2, předtím je ale nutné vytvořit hlavičkový soubor pro naši knihovnu /*
Hlavičkový soubor lib.h deklarující funkce pozdrav1 a pozdrav2 */ void pozdrav1 (int); void pozdrav2 (char *);
Filip Malý KIKM FIM UHK
16
Nástroje a vývojové prostředky 7
Je pak vhodné doplnit hlavičkový soubor do souborů pozdrav1.c a pozdrav2.c. Pak vytvoříme program program.c #include "lib.h" (pozn: „“ naše lokální knihovna) int main() { pozdrav2("Ahoj, jak se mate?"); return 0; }
Následně program přeložíme a vyzkoušíme, specifikujeme objektové soubory explicitně tak, že požádáme překladač, aby přeložil náš soubor a připojil k němu dříve přeložený modul pozdrav2.o $ gcc -c program.c $ gcc -o program program.o pozdrav2.o $ ./program
Filip Malý KIKM FIM UHK
17
Nástroje a vývojové prostředky 8 Dále vytvoříme knihovnu Programem ar vytvoříme archiv a do něj přidáme naše objektové soubory $ ar crv libpozdravy.a pozdrav1.o pozdrav2.o a – pozdrav1.o a – pozdrav2.o
Vytvořili jsme knihovnu a do ní přidali dva objekty, ještě je nutné (kvůli některým systémům) vytvořit obsah knihovny pomocí aplikace ranlib $ ranlib libpozdravy.a Filip Malý KIKM FIM UHK
18
Nástroje a vývojové prostředky 9 Následně lze knihovnu použít pro sestavení programu $ gcc -o program program.o libpozdravy.a $ ./program Lze použít i přepínač -l a sdělit, kde ji překladači, kde knihovnu nalezne pomocí -L $ gcc -o program program.o -L. -lpozdravy Obsah funkcí v té které knihovně získáme pomocí příkazu nm Odkaz na hlavičkový soubor způsobí začlenění jen těch funkcí, které program skutečně potřebuje (nezačlení tedy všechny funkce knihovny)
Filip Malý KIKM FIM UHK
19
Nástroje a vývojové prostředky 10 Sdílené knihovny Nevýhoda statických knihoven – pokud je spuštěno více programů, které používají stejnou knihovnu, funkce budou v paměti tolikrát, kolik je spuštěno programů, které dané funkce využívají; navíc tytéž funkce budou obsaženy v samotných programech (v tělech programů) Řeší nevýhody statických knihoven Umístěny na stejných místech jako statické, mají koncovku .so.N, kde N je číslo verze Program využívající sdílené knihovny je sestavován tak, aby jeho tělo neobsahovalo funkce sdílené knihovny, ale jen odkaz na sdílený kód, který bude k dispozici až za běhu Filip Malý KIKM FIM UHK
20
Nástroje a vývojové prostředky 11 Díky tomu tento systém zajišťuje, aby při spuštění více programů bylo využíváno jen jedné kopie sdílené knihovny v paměti (i na disku) Lze aktualizovat knihovnu nezávisle na aplikacích, které ji využívají Pomocí programu ldd zjistíme, jaké knihovny aplikace potřebuje Dynamický zavaděč v Linuxu, který nahrává a řeší závislosti se nazývá ld.so nebo ls-linux.so.2 Knihovny .so jsou podobné DLL ve Windows a jsou potřebné za běhu, knihovny .sa se podobají souborům LIB, které jsou začleňovány do těla programu Filip Malý KIKM FIM UHK
21
Filozofie operačního systému UNIX Jednoduchost Utility jednoduché, snadné, malé Zaměření Program dělající jednu úlohu a dělající ji pořádně, kombinace těchto programů Znovupoužitelné komponenty Jednoduché a flexibilní rozhraní Filtry Spousta unixových aplikací jako filtry, které převádějí vstup na výstup jiného typu Otevřené formáty souborů Konfigurační a datové soubory jako textové ASCII soubory Výhodné – lze totiž prohledávat a snadno měnit konfigurace Filip Malý KIKM FIM UHK
22
Základní příkazy (abecedně)
alsaconf - Nastavení ALSA - Advancend Linux Sound Architecture alsamixer - Ovládá hlasitosti zvuků zařízení běžících přes ALSA apt-get - Balíčkovací systém distribucí s .deb balíčky (Debian, Ubuntu) at - Spouští příkazy v zadanou dobu bzip2 - Zabalí a rozbalí - (de)komprimuje - soubor cat - Vypíše nebo spojí soubory cd - Přechod mezi adresáři. Pokud nezadáte žádný parametr, přejde se do ~ clear - Vyčistí okno terminálu cp - Kopírování souborů df - Volné místo na oddílech du - Zobrazí součet velikosti souborů v adresáři date - Vypíše datum a čas eject - Vysunutí a zasunutí mechaniky Filip Malý KIKM FIM UHK
23
Základní příkazy (abecedně)
emerge - Ovládání balíčkovacího systému Gentoo (Portage) exit - Odhlásí uživatele file - Zobrazí typ souboru find - Vyhledává soubory a provádí s nimi různé akce finger - Zobrazuje informace o uživatelích systému fmt - Provádí jednoduché formátování textu free - Obsazení paměti grep - Vyhledání řetězce groups - Vypíše skupiny, do kterých je uživatel zařazen gzip - Zabalí a rozbalí - (de)komprimuje - soubor halt - Vypne systém chattr - Program pro změnu atributů souborů na ext filesystémech chgrp - Mění skupinu souborů/adresářů chmod - Mění přístupová práva k soubor Filip Malý KIKM FIM UHK
24
Základní příkazy (abecedně)
chown - Mění vlastníka souborů/adresářů iconv - Konvertuje znakovou sadu id - Zobrazí jméno a číslo přihlášeného uživatele a skupin, do kterých patří init - Spustí nebo ukončí aplikace podle nastavení v /etc/init.d ip - Ucelená konfigurace sítě iptables - Paketový filtr. Využívá se jako firewall, tvorbu NATu a další kill - Ukončuje proces dle zadaného PID killall - Ukončuje všechny procesy se zadaným jménem less - Vypisuje obsah textových souborů ln - Vytváří odkazy na soubory locate - Slouží ke hledání souborů. Před použitím je nutno spustit updatedb logout - Odhlásí vás ze systému ls - Vypíše obsah aktuálního adresáře lsattr - Zobrazí atributy souboru na ext filesystémech lsmod - Vypíše seznam modulů načtených do jádra Filip Malý KIKM FIM UHK 25 mkdir - Vytváří adresáře
Základní příkazy (abecedně)
mkinitramfs, mkinitrd, mkinitcpio - Vytváří inicializační ramdisky obsahující moduly, které jsou nutné při zavádění jádra modprobe - Načítá moduly mount - Připojuje disky more - Podobně jako less umožňuje pozastavit výpis most - Vylepšená verze programů less a more mv - Přesouvá nebo přejmenovává soubory pacman - Balíčkovací systém distribuce ArchLinux ping - Provede měření odezvy zadaného počítače nebo jiného síťového prvku passwd - Mění heslo uživatele pgrep - Vypíše PID zadaného procesu poweroff - Vypnutí počítače ps - Vypíše seznam běžících procesů pwd - Vypíše cestu k aktuálnímu adresáři Filip Malý KIKM FIM UHK
26
Základní příkazy (abecedně)
reboot - Restart systému reset - Resetování terminálu rm - Maže soubory nebo adresáře rmdir - Maže prázdné adresáře shutdown - Vypne nebo restartuje počítač sort - Třídí položky startx - Spustí systém X Window su - Přepíná uživatele sudo - Spustí příkaz pod superuživatelem tar - Zabalí a rozbalí data top - Zobrazuje výpis procesů a jejich nároky na systémové zdroje v reálném čase tree - Vypíše obsah adresáře jako strom tty - Vypíše virtuální zařízení terminálu připojeného na standardní vstup Filip Malý KIKM FIM UHK
27
Základní příkazy (abecedně)
uptime - Zobrazí aktualní čas (hh:mm:ss), dobu jakou je systém spuštěn, počet přihlášených uživatelů a informaci o průměrném zatížení systému urpm - Balíčkovací systém distribucí používajících RPM (Redhat, Mandriva, Fedora ...) uname - Zobrazí název jádra, s parametrem -a přidá i verzi, název počítače a systému uniq - Odstraní ze souboru duplicitní řádky umount - Odpojuje disky vmstat - Zobrazí statistiku o zaplnění virtuální paměti, využití cpu, přerušení,... w - Vypíše seznam přihlášených uživatelů a zobrazí, co dělají wc - Vypíše počet řádků, slov a znaků v souboru wget - Stáhne soubor z internetu Filip Malý KIKM FIM UHK
28
Základní příkazy (abecedně) whereis - Vyhledá zdrojové kódy, binární soubory a/nebo manuálové stránky pro zadaný příkaz. who - Seznam přihlášených uživatelů. whoami - Vypíše uživatelské jméno aktuálně přihlášeného uživatele. which - Zobrazí plnou cestu k programu (příkazu shellu). wine - Spustí binární soubor určený pro systém Microsoft Windows. yast2 - Spustí komplexní nastavovací nástroj zpravidla v opensuse. yum - Balíčkovací systém distribuce Fedora Core Filip Malý KIKM FIM UHK
29
C jako jazyk pro systémové programování
Obsah prezentace
Základní pojmy Datové typy Definice proměnných Přiřazení Hlavní program Konstanty
Celočíselné Reálné Znakové Literály
Unární Binární
Aritmetické výrazy
Vstup a výstup znaků Řídicí struktury
Booleovské výrazy Ternární operátor Operátor čárky if, if-else break, continue while do-while for switch goto return
Explicitní přetypování Filip Malý KIKM FIM UHK
2
Jazyk C „Jazyk C vznikl v UNIXu proto, aby v něm mohl být naprogramován UNIX.“ První UNIX 1969 napsán převážně v asembleru, v něm vytvořen jazyk C Roku 1970 představen UNIX napsaný v C (1000 řádku v asembleru, 10000 řádků v C) Filip Malý KIKM FIM UHK
3
Základní pojmy
Editor – pomocí něj píšeme zdrojové kódy Preprocesor – součást překladače, předzpracovává (upravuje) zdrojový soubor tak, aby měl překladač snadnější práci
Vynechává komentáře, zajišťuje správné vložení hlavičkových souborů .h, rozvoj maker, … Výsledkem textový soubor poslaný kompilátoru
Obsahuje náš program ve formě zdrojového kódu
Umožní správně využít knihovní funkce, #include <stdio.h>
Compiler – kompilátor, překladač – provádí překlad zdrojového souboru do relativního (objektového) kódu, vzniká .o soubor Linker – sestavovací program – v relativním kódu nahradí relativní adresy absolutními adresami a provede všechny odkazy na dosud neznámé identifikátory (například knihovní funkce v lib, …), výsledkem je spustitelný soubor Debugger - „odvšivovač“, ladící program Zdrojový soubor .c Hlavičkový soubor .h
Filip Malý KIKM FIM UHK
4
Datové typy
int long int (long) short int (short) char float double long double Filip Malý KIKM FIM UHK
5
Definice proměnných Definice = příkaz, který přidělí proměnné určitého typu jméno a paměť Deklarace = příkaz, který pouze udává typ proměnné a její jméno, deklarace nepřiděluje žádnou paměť (nerozumíte? Viz dále:-) ) Definice v C int i; char c, ch; float f, g; Globální a lokální proměnná int i; /* globální proměnná */ main() { int j;/* lokální proměnná */ } Filip Malý KIKM FIM UHK
6
Definice a deklarace Deklarace funkce int secti(int a, int b); Definice funkce int secti(int a, int b){ return a + b; } Filip Malý KIKM FIM UHK
7
Přiřazení l-hodnota představuje adresu, tzn. proměnná je l-hodnota, konstanty nebo výrazy nikoliv výraz
expression
výraz
i * 2 + 3
přiřazení
assigment
l-hodnota=výraz
j = i * 2 + 3
příkaz
statement l-hodnota=výraz; j = i * 2 + 3;
j = 5; d = ‘z’; f = f + 3.14 * i; Filip Malý KIKM FIM UHK
8
Hlavní program main() /* bez středníku */ { int i, j; i = 5; j = -1; j = j + 2 * i; } (poznámka: chybí int main a návratová hodnota) Filip Malý KIKM FIM UHK
9
Konstanty Celočíselné Desítkové 15, 0, 1 Oktalové 065, 015, 0, 01 Hexadecimální 0x12, 0X3A, 0XCD, 0xCD, 0Xcd, 0x15, 0x0, 0x1
Reálné 15., 56.8, .84, 3.14, 5e6, 7E23 Reálná konstanta typu float 3.14f nebo 3.14F Reálná konstanta typu long 12e3L, 12l (nedoporučuje se používat znak „l“, připomíná jedničku „1“) Filip Malý KIKM FIM UHK
10
Konstanty Znakové konstanty
'a', '*', '4' velikost znakové konstanty není char, ale int (například for (i=‘A’; i<=‘Z’; …)) Konstanty z neviditelných znaků - '\ddd', kde ddd je oktalové číslo, takže třeba '\012', '\007' Escape sekvence
Řetězové konstanty – literály
“Toto je řetězová konstanta“ ANSI C umožňuje zřetězování dlouhých literálů oddělených mezerami, tabelátory nebo novými řádky “Toto je velmi “
“dlouhý text“
Filip Malý KIKM FIM UHK
11
Aritmetické výrazy i = 2 je výraz s přiřazením i = 2; je příkaz Unární + a -
Binární +, -, *, / (reálné dělení), / (celočíselné dělení), % (dělení modulo) Celočíselné int / int Reálné int / float, float / int, float / float Filip Malý KIKM FIM UHK
12
Aritmetické výrazy Speciální unární
Inkrement ++ Dekrement - vyraz++ = po použití vrácena původní hodnota výrazu, pak je výraz zvětšen o jedničku ++vyraz = před použitím výraz nejprve zvětšen o jedničku a pak je tato nová hodnota vrácena
Přiřazovací operátory
= +=, -=, *=, … například l-hodnota += výraz znamená l-hodnota = l-hodnota + výraz Filip Malý KIKM FIM UHK
13
Vstup a výstup znaků getchar, putchar #include <stdio.h> main() { int c; c = getchar(); putchar(c); putchar('\n'); } getchar načítá, dokud nestikneme enter, pak načte jen první znak
Filip Malý KIKM FIM UHK
14
Vstup a výstup znaků scanf, printf #include <stdio.h> main() { int i, j; scanf(“%d“, &i); scanf(“%d“, &j); printf(“%d%d“, j, i); printf(“%d je soucet“, i + j); } Výstupem programu bude pro vstup 4 a 7 „7411 je soucet“ (nejsou odděleny oba výpisy) Filip Malý KIKM FIM UHK
15
Vstup a výstup znaků
Řídicí řetězce
c – znak d – desítkové číslo typu signed int ld – desítkové číslo typu signed long u – desítkové číslo typu unsigned int lu – desítkové číslo typu unsigned long f – float (pro printf také double) Lf – long double (L musí být velké) lf – double (někdy nelze použít pro printf) x – hexadecimální číslo malými písmeny (například 1a2c) X – hexadecimální číslo velkými písmeny (například 1A2C) o – osmičkové číslo s – řetězec
Filip Malý KIKM FIM UHK
16
Řídicí struktury
Booleovské výrazy
používá se typ int a 0 nebo 1, kde 0 = false a 1 = true == rovnost, != nerovnost, && logický součet, || logický součin, ! negace, < menší, <= menší nebo rovno, > větší, >= větší nebo rovno při pochybách s prioritou vyhodnocování závorkovat
Podmíněný výraz – ternární operátor
výraz_podmínka ? výraz_1 : výraz_2 = if výraz_podmínka then výraz_1 else výraz_2
int i, k, j = 2; i = (j == 2) ? 1 : 3; /* i bude 1 */ k = (i > j) ? i : j; /* k bude maximum z i a j, tj. 2 */ (i == 1) ? i++ : j++;/* možnosti inkrementace */
Filip Malý KIKM FIM UHK
17
Řídicí struktury Operátor čárky výraz_1, výraz_2 – výraz_1 se vyhodnotí a pak je tento výsledek zapomenut, dále se vyhodnotí výraz_2 a to je také závěrečný výsledek int i = 2, j = 4; /* toto není operátor čárky */ j = (i++, i – j); /* toto je operátor čárky – i bude 3 a j bude -1 */ Filip Malý KIKM FIM UHK
18
Řídicí struktury
if, if-else if (i > 3) j = 5; if (i > 3) j = 5; else j = 10; if (i > 3) { j = 5; i = 7; } else { j = 1; } Filip Malý KIKM FIM UHK
19
Řídicí struktury break, continue break ukončuje nejvnitřnější neuzavřenou smyčku – opouští okamžitě cyklus continue skáče na konec nejvnitřnější neuzavřené smyčky a tím vynutí další iteraci smyčky – cyklus neopouští
goto V dobře psaných programech se nepoužívá (není potřeba) Návěští, kterým se dá kamkoliv skočit Filip Malý KIKM FIM UHK
20
Řídicí struktury while while (i > 3) {
i--; }
for for (i = 1; i <= 10; i++) { }
for ( ; ; )
/* nekonečný cyklus */ Filip Malý KIKM FIM UHK
21
Řídicí struktury
do-while int c; do { c = getchar(); } while (c != 'z');
switch switch (getchar()) { case 'a' : case 'b' : case 'c' : putchar('1'); case 'd' : putchar('2'); case 'e' : putchar('3'); break; case 'd' : putchar('4'); putchar('5'); break; default :putchar('6'); }
Filip Malý KIKM FIM UHK
22
Řídicí struktury return Ukončí provádění funkce, další příkazy za ním se už neprovedou Ve funkci main ukončí celý program Často se pomocí return vrací nějaká hodnota
if (i > j) return 0; else return 1; Filip Malý KIKM FIM UHK
23
Řídicí struktury Explicitní přetypování int i = 10; double f; f = sqrt((double) i);
Filip Malý KIKM FIM UHK
24
Skripty, volání, příkazy, shelly
Obsah prezentace Co je to shell Roury a přesměrování Shell jako programovací jazyk
Syntaxe shellu
Filip Malý KIKM FIM UHK
Proměnné Podmínky Řídicí struktury Seznamy Funkce Příkazy Dokumenty here Ladění skriptů
2
Co je to shell
V podstatě skutečný programovací jazyk Lze v něm provádět příkazy, volat programy, psát programy Interpretovaný jazyk Není vhodný pro úlohy kritické nebo časově náročné na procesor Je ideální pro malé utility Proč ho používat
Programuje se v něm rychle a jednoduše, je dostupný snad na všech UNIXech
Obvykle platí, že je lepší utilitu napsat nejprve v shellu
Pokud je nedostatečně rychlá, přepsat ji například do jazyka C nebo C++ Pokud je dostatečně rychlá, ponechat ji v shellu
Filip Malý KIKM FIM UHK
3
Co je to shell Program fungující jako rozhraní mezi uživatelem a systémem UNIX Umožňuje zadávat příkazy, které má OS vykonat Přesměrování souborů <, >, roura | Výstup z vnořeného procesu pomocí $(...)
Filip Malý KIKM FIM UHK
4
Co je to shell
Různé shelly:
sh – původní shell Bourne csh, tcsh, zsh – C shell (Bill Joy, Berkely), nejoblíbenější po shellu bash ksh, pdksh – Korn shell a jeho volně dostupný „bratranec“ bash – základ Linuxu z projektu GNU, bash neboli Bourne Again Shell má volně dostupný kód a byl portován na většinu běžných UNIXů rc – shell, který je více „céčkový“ než csh, také z projektu GNU
Až na C shell jsou si ostatní velice podobné a spjaté se specifikacemi X/Open 4.2 a POSIX 1003.2 /bin/sh nebo /bin/bash – mnohdy je cesta /bin/sh odkazem na nějaký používaný shell, často /bin/bash (verze shellu: /bin/bash -version nebo echo $BASH_VERSION)
Filip Malý KIKM FIM UHK
5
Roury a přesměrování Přesměrování vstupu a výstupu unixových programů Přesměrování výstupu $ ls -l > lsvystup.txt uloží výstup příkazu ls do souboru lsvystup.txt Soubor bude přepsán (pokud již existuje) Toto chování lze změnit pomocí set -C nastavit volbu noclobber Pokud chceme, aby byl výstup k existujícímu souboru připojen $ ls -l >> lsvystup.txt Filip Malý KIKM FIM UHK
6
Roury a přesměrování Deskriptory 0 = standardní vstup 1 = standardní výstup 2 = standardní chybový výstup Všechny lze nezávisle přesměrovat
Přesměrování standardního chybového výstupu $ kill -HUP 1234 > killvystup.txt 2> killchyba.txt
Použijeme operátor 2> pro přesměrování standardního chybového výstupu Filip Malý KIKM FIM UHK
7
Roury a přesměrování Standardní i chybový výstup do jednoho souboru $ kill -1 1234 > killvystup.txt 2>&1 „přesměruj standardní výstup do souboru killvystup.txt a potom přesměruj standardní chybový výstup do stejného místa“
/dev/null $ kill -1 1234 > /dev/null 2>&1 nechceme vidět standardní výstup ani standardní chybový výstup Filip Malý KIKM FIM UHK
8
Roury a přesměrování Přesměrování vstupu $ more < killvystup.txt ovšem v tomto případě more přijímá názvy souborů jako parametry
Roury Pomocí operátoru | lze procesy vzájemně propojovat Procesy propojené rourami mohou běžet současně, data tak putují mezi nimi, jsou předávána automaticky Filip Malý KIKM FIM UHK
9
Roury a přesměrování sort a ps – setřídíme výpis procesů $ ps > psout.txt $ sort psout.txt > pssort.txt $ ps | sort > pssort.txt elegantně nahradí předchozí dva příkazy
$ ps | sort | more uvidíme výstup po stránkách
Všechna různá jména procesů kromě shellu $ ps -xo comm | sort | uniq | grep -v sh | more Filip Malý KIKM FIM UHK
10
Shell jako programovací jazyk
Interaktivní programy
Ukázkový kód, který lze napsat přímo do shellu – píšeme do shellu po řádcích (shell změní prompt na znak >) a po posledním done shell sám pozná konec a skript – příkazy spustí $ for file in * > do > echo $file > done seznam souboru $
Expanze znaků
? zastupuje jediný znak, [množina] množina povolených znaků, [^množina] množina nepovolených znaků, * zastupuje více znaků, {} závorková expanze umožňuje seskupit do jedné množiny různé řetězce, jejichž expanzi pak shell provádí $ ls my_{funger,toe}s vypíše dva soubory mající společné identifikátory (v aktuálním adresáři)
Filip Malý KIKM FIM UHK
11
Shell jako programovací jazyk Vytvoření skriptu Vytvoříme soubor prvni.sh #!/bin/sh # jednořádkový komentář programu for file in * do echo $file done exit 0 Filip Malý KIKM FIM UHK
12
Shell jako programovací jazyk
První řádek #!/bin/sh je zvláštní formou komentáře, kterým cosi sdělujeme systému
Příkaz exit 0 zajistí rozumnou návratovou hodnotu, bezchybný návrat
Zde sdělujeme, jaký shell se má spustit pro provádění našeho skriptu Používá se v případě volání více skriptů, kde si mezi sebou mohou tuto hodnotu předávat a dle toho postupovat
Skript spustíme
$ /bin/sh prvni.sh
$ chmod +x prvni.sh a pak $ prvni.sh, případně $ ./prvni.sh
Filip Malý KIKM FIM UHK
13
Syntaxe shellu Proměnné $ pozdrav=Ahoj $ echo $pozdrav vypíše text „Ahoj“ $ pozdrav=7+5 $ echo $pozdrav vypíše „7+5“
$ pozdrav=“Ahoj lidi“ $ echo $pozdrav vypíše „Ahoj lidi“ nutno tedy více slov uzavřít do uvozovek Filip Malý KIKM FIM UHK
14
Syntaxe shellu Uvozovky Dvojité uvozovky = jeden výraz, například „Ahoj lidi“ Jednoduché uvozovky = substituce se neprovádí promenna=“Ahoj lidi“ echo $promenna vypíše „Ahoj lidi“ echo “$promenna“ vypíše „Ahoj lidi“ echo '$promenna' vypíše promenna echo \$promenna vypíše promenna Filip Malý KIKM FIM UHK
15
Syntaxe shellu Proměnné prostředí $HOME domovský adresář uživatele $PATH seznam adresářů oddělených dvojtečkami, ve kterých se mají hledat příkazy $PS1 prompt příkazové řádky, obvykle $ $PS2 druhý prompt využívaný při dodatečném vstupu, obvykle > $IFS oddělovač polí, seznam znaků, které slouží k oddělování slov, když shell čte vstup, obvykle mezera, tabulátor a znak nový řádek $0 název skriptu $# počet předaných parametrů $$ id procesu skriptu, které se často používá uvnitř shellu ke generování jedinečných názvů dočasných souborů, například /tmp/tmpfile_$$ Filip Malý KIKM FIM UHK
16
Syntaxe shellu Proměnné – parametry $1, $2, … parametry předané skriptu $* seznam všech parametrů uložených v jedné proměnné a oddělených prvním znakem uvedeným v proměnné IFS $@ varianta $*, která nepoužívá proměnnou prostředí IFS
Filip Malý KIKM FIM UHK
17
Syntaxe shellu
Podmínky
test nebo []
logické výrazy shellu
if test -f soubor.txt then … fi
if [ -f soubor.txt ] pozor, musí být dodrženy mezery then … fi if [ -f soubor.txt ]; then … fi
Filip Malý KIKM FIM UHK
18
Syntaxe shellu
Testování řetězců
řetězec1 = řetězec2 pravda, jsou-li stejné řetězec1 != řetězec2 pravda, nejsou-li stejné -n řetězec pravda, není-li řetězec nulový -z řetězec pravda, je-li řetězec nulový (prázdný řetězec)
Numerické testy
výraz1 -eq výraz2 pravda, jsou-li si výrazy rovny výraz1 -ne výraz2 pravda, pokud si výrazy nejsou rovny výraz1 -gt výraz2 pravda, je-li výraz1 větší než výraz2 výraz1 -ge výraz2 pravda, je-li výraz1 větší nebo roven výrazu2 výraz1 -lt výraz2 pravda, je-li výraz1 menší než výraz2 výraz1 -le výraz2 pravda, je-li výraz1 menší nebo roven výrazu2 ! výraz pravda, je-li výraz nepravdivý a naopak
Filip Malý KIKM FIM UHK
19
Syntaxe shellu
Testy souborů
-d soubor pravda, je-li soubor adresářem -e soubor pravda, pokud soubor existuje -f soubor pravda, je-li soubor normálním souborem -g soubor pravda, má-li soubor nastaven příznak set-group-id -r soubor pravda, je-li soubor možno číst -s soubor pravda, má-li soubor nenulovou délku, -u soubor pravda, má-li soubor nastaven příznak set-user-id -w soubor pravda, je-li do souboru možné zapisovat -x soubor pravda, je-li soubor spustitelný Historicky nebylo možné přenést volbu -e, proto se používá spíše volba -f set-group-id, set-user-id také jako set-gid a set-uid, například set-user-id přiděluje programu místo oprávnění uživatele oprávnění svého vlastníka Všechny testy vyžadují, aby soubor existoval Filip Malý KIKM FIM UHK
20
Syntaxe shellu – řídicí struktury
if podmínka then else
fi
příkazy příkazy
echo “Je ted rano?“ read rano if [ “$rano“ = “ano“ ]; then echo “Dobre rano“ else echo “Dobry den“ fi exit 0 Filip Malý KIKM FIM UHK
21
Syntaxe shellu – řídicí struktury
elif echo “Je ted rano?“ read rano if [ “$rano“ = “ano“ ]; then echo “Dobre rano“ elif [ “$rano“ = “ne“ ] echo “Dobry den“ else echo “Spatna volba“ fi
exit 0
Filip Malý KIKM FIM UHK
22
Syntaxe shellu – řídicí struktury
for proměnná in hodnoty do
příkazy done
until podmínka do
příkazy done until who | grep “$1“ > /dev/null do sleep 60 done
Filip Malý KIKM FIM UHK
23
Syntaxe shellu – řídicí struktury
while podmínka do příkazy done
echo “Zadej heslo“ read zkus while [ “$zkus“ != “heslo“ ]; do echo “Spatne, zkus znovu!“ read zkus done
další příklad foo=1 while [ "$foo" -le 20 ] do echo "Here we go again" foo=$(($foo+1)) # znamená „foo = foo + 1“ done
Filip Malý KIKM FIM UHK
24
Syntaxe shellu – řídicí struktury
case proměnná in
příklad 1
vzorek [ | vzorek] …) příkazy;; vzorek [ | vzorek] …) příkazy;; ... esac
echo "Is it morning? Please answer yes or no" read timeofday case "$timeofday" in "yes") echo "Good Morning";; "no" ) echo "Good Afternoon";; "y" ) echo "Good Morning";; "n" ) echo "Good Afternoon";; * ) echo "Sorry, answer not recognised";; esac Filip Malý KIKM FIM UHK
25
Syntaxe shellu – řídicí struktury case příklad 2 echo "Is it morning? Please answer yes or no" read timeofday case "$timeofday" in yes | y | Yes | YES ) echo "Good Morning";; n* | N* ) echo "Good Afternoon";; * ) echo "Sorry, answer not recognised";; esac Filip Malý KIKM FIM UHK
26
Syntaxe shellu – řídicí struktury
case příklad 3 echo "Is it morning? Please answer yes or no" read timeofday case "$timeofday" in yes | y | Yes | YES ) echo "Good Morning" echo "Up bright and early this morning?" ;; [nN]* ) echo "Good Afternoon" ;; * ) echo "Sorry, answer not recognised" echo "Please answer yes or no" exit 1 ;; esac
Filip Malý KIKM FIM UHK
27
Syntaxe shellu
Seznam AND
zkrácené vyhodnocování AND && – vyhodnocování probíhá zleva doprava, vrátí-li výraz true, postupuje se dál, jinak provádění seznamu skončí (projde-li se celý seznam, všechny příkazy vrátily hodnotu true)
touch file_one rm -f file_two if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there" then echo -e "in if" else echo -e "in else" fi
Filip Malý KIKM FIM UHK
28
Syntaxe shellu
Seznam OR
OR || – vyhodnocování probíhá zleva doprava, vrátí-li výraz false, postupuje se dál, jinak provádění seznamu skončí (projde-li se celý seznam, všechny příkazy vrátily hodnotu false) rm -f file_one if [ -f file_one ] || echo "hello" || echo "there" then echo "in if" else echo "in else" fi
[ -f soubor ] && příkaz pro true || příkaz pro false bude-li test úspěšný, provede se první příkaz, jinak se provede druhý příkaz
Bloky příkazů
V místě, kde je povolen jen jeden příkaz lze více příkazů uzavřít do {}
Filip Malý KIKM FIM UHK
29
Syntaxe shellu Funkce #!/bin/sh foo() { echo "Function foo is executing" } echo "script starting" foo echo "script ended" exit 0 Při volání funkce jsou poziční parametry ($*, $@, $#, $1, $2, …) nahrazeny parametry funkce, po skončení jsou obnoveny původní parametry (na to se ale nelze spoléhat u starších shellů)
Filip Malý KIKM FIM UHK
30
Syntaxe shellu Funkce Předání parametrů pomocí slova return, anebo dle následujícího příkladu foo () { echo JAY;} … result=“$(foo)“
Lokální proměnná Uvnitř funkce použijeme před názvem proměnné slovo local Proměnná má platnost po dobu provádění funkce Filip Malý KIKM FIM UHK
31
Syntaxe shellu – příkazy
break slouží k odskoku z cyklu for, while, until, zruší jednu úroveň cyklu : nulový příkaz, zjednodušení podmínky – zastupuje hodnotu true continue spustí další iteraci cyklů for, while, until, do proměnné cyklu je přiřazena další hodnota ze seznamu . provede příkaz v aktuálním shellu (také source)
pomocí tečky lze třeba přenést proměnné do shellu (když se spustí skript v shellu, je pro tento skript spuštěn vlastně další shell, ve kterém je pak skript prováděn) tečka způsobí spuštění příkazu uvedených ve skriptu v rámci stejného shellu, který skript vyvolal
echo výpis řetězce a nový řádek, raději používat printf, potlačení řádku echo -n “text“ nebo echo -e “text\c“
Filip Malý KIKM FIM UHK
32
Syntaxe shellu – příkazy eval vyhodnocování argumentů foo=10 x=foo y='$'$x echo $y vrátí hodnotu $foo
foo=10 x=foo eval y='$'$x echo $y vrátí hodnotu 10 Filip Malý KIKM FIM UHK
33
Syntaxe shellu – příkazy exec poskytuje dvě různé možnosti nahrazování aktuálního shellu jiným programem exec wall “Sbohem a díky za všechny ryby“
způsobí, že ve skriptu bude aktuální shell nahrazen příkazem wall a všechny ostatní příkazy uvedené za příkazem exec se už neprovedou umožňuje upravit deskriptory exec 3< soubor způsobí, že deskriptor 3 bude otevřen pro čtení ze souboru soubor (používá se málokdy) Filip Malý KIKM FIM UHK
34
Syntaxe shellu – příkazy
exit n způsobí ukončení skriptu s návratovým kódem
n = 0 znamená úspěšné ukončení n = 1 až 125 pak chybové kódy další hodnoty jsou rezervovány
126 soubor nebyl spustitelný 127 příkaz nenalezen 128 a vyšší objevil se nějaký signál
if [ -f soubor.txt ]; then exit 0 fi exit 1 anebo pomocí seznamu jako
[ -f soubor.txt ] && exit 0 || exit 1
export zpřístupní proměnnou, která je předána příkazu export jako parametr, podřízenému shellu Filip Malý KIKM FIM UHK
35
Syntaxe shellu – příkazy expr vyhodnocuje své argumenty, jako by se jednalo o výraz, používá se pro jednoduché aritmetické výpočty typu x='expr $x + 1' mezi výrazy jsou možné operátory |, &, =, >, >=, <, <=, !=, +, -, *, / (celočíselný podíl), % (zbytek po celočíselném dělení) v novějších skriptech je nahrazován zápisem $((...)), například x=$(($x+1))
Filip Malý KIKM FIM UHK
36
Syntaxe shellu – příkazy
printf jen v moderních shellech printf “formátovací řetězec“ parametr1 parametr2 … Formátovací řetězec
Konverzní specifikátory
\\ zpětné lomítko \a varování (pípnutí) \b zpětné lomítko \b znak vysunutí stránky \n nový řádek \r návrat vozíku \t znak tabulátoru \v vertikální tabulátor \ooo znak, jehož osmičková hodnota je ooo d c s %
vypíše vypíše vypíše vypíše
desítkové číslo znak řetězec procento
Nejsou podporovány reálné proměnné, protože veškerá aritmetika v shellu probíhá v oboru celých čísel Filip Malý KIKM FIM UHK
37
Syntaxe shellu – příkazy return návrat z funkce má jediný číselný parametr, který je předán skriptu, jenž danou funkci zavolal není-li parametr uveden, vrací příkaz return implicitně návratový kód posledního příkazu
set nastavuje proměnné shellu lze také řídit chování shellu
shift způsobí posun všech pozičních parametrů z $2 se stane $1 a předchozí hodnota v $1 zmizí hodnota v $0 zůstává zachována Filip Malý KIKM FIM UHK
38
Syntaxe shellu – příkazy trap specifikace akcí, které se mají provést po přijetí určitých signálů trap příkaz signál Příkaz trap je nutné provést ještě před částí skriptu, kterou chceme takto ochránit Implicitní podmínka trap . Signál Ignorování prázdný řetězec trap ““ signál Signály
HUP 1 posílán, když spadne terminál nebo se odhlásí uživatel INT 2 generován Ctrl+c QUIT 3 generován stiskem Ctrl+\ ABRT 6 posílán při vážných chybách ALRM 14 většinou se používá pro obsluhu vypršení času TERM 15 obvykle ho zasílá systém při ukončení Filip Malý KIKM FIM UHK
39
Syntaxe shellu – příkazy
trap příklad #!/bin/sh trap echo date echo
'rm -f /tmp/my_tmp_file_$$' INT creating file /tmp/my_tmp_file_$$ > /tmp/my_tmp_file_$$ "Press interrupt (Ctrl-C) to interrupt...."
while [ -f /tmp/my_tmp_file_$$ ]; do echo File exists sleep 1 done echo trap echo date echo
"The file no longer exists" INT creating file /tmp/my_tmp_file_$$ > /tmp/my_tmp_file_$$ "Press interrupt (Ctrl-C) to interrupt...."
while [ -f /tmp/my_tmp_file_$$ ]; do echo File exists sleep 1 done echo "We never get here" exit 0
Filip Malý KIKM FIM UHK
40
Syntaxe shellu – příkazy unset odstraní z prostředí proměnnou nebo funkci netýká se proměnných určených jen ke čtení
provádění příkazů pomocí $(příkaz)
Filip Malý KIKM FIM UHK
41
Syntaxe shellu – expanze parametrů
Expanze parametrů foo=fred echo $foo
Připojení dalších znaků na konec proměnné for i in 1 2 do echo promenna ${i}_tmp done
Parametry
${parametr:-implicitní} je-li parametr prázdný, použij implicitní hodnotu ${parametr} vrátí délku parametru ${parametr%slovo} od konce odstraní nejkratší část parametru, která odpovídá slovu a vrátí zbytek ${parametr%%slovo} od konce odstraní nejdelší část parametru, která odpovídá slovu a vrátí zbytek ${parametr#slovo} od začátku odstraní nejkratší část parametru, která odpovídá slovu a vrátí zbytek ${parametr##slovo} od začátku odstraní nejdelší část parametru, která odpovídá slovu a vrátí zbytek
Filip Malý KIKM FIM UHK
42
Syntaxe shellu – dokumenty here Speciální způsob předávání vstupu příkazu ze skriptu shellu Umožňuje to daný příkaz provést, jakoby četl ze souboru nebo z klávesnice, zatímco získává vstup ze skriptu Začínají << následované speciální sekvencí znaků, které se budou opakovat na konci dokumentu Sekvence slouží jako jakási značka, měla by být proto jedinečná Filip Malý KIKM FIM UHK
43
Syntaxe shellu – dokumenty here #!/bin/sh cat <
Výstupem jsou postupně řádky obsahující „ahoj“, „toto je nejaky“, „dokument“ Filip Malý KIKM FIM UHK
44
Syntaxe shellu – dokumenty here
příklad (předpokladem je, že máme textový soubor textfile obsahující čtyři věty typu „Toto je řádek X“, kde X je číslo řádku) #!/bin/sh ed textfile <
Pak výstupem tohoto skriptu bude Toto je řádek 1 Toto je řádek 2 Toto byl řádek 4
Filip Malý KIKM FIM UHK
45
Syntaxe shellu Ladění skriptů shell vytiskne číslo řádku, na kterém došlo k chybě sh -a <skript> a set -o noexec a set –a kontroluje jen syntaktické chyby a neprovádí příkazy
sh -v <skript> a set -o verbose a set -v před zpracováním příkazy vypíše
sh -x <skript> a set -o xtrace a set -x po zpracování příkazy vypíše
sh -x <skript> a set -o nounset a set -u v případě použití nedefinované proměnné vrátí zprávu o chybě
Pomocí -o nebo +o lze tyto volby zapínat a vypínat
Filip Malý KIKM FIM UHK
46
Struktura a architektura systému
Obsah prezentace Vstup uživatele do systému Základní schéma komunikace Soubory
Standardní vstupy, výstupy, přesměrování Speciální soubory Změna atributů Systém souborů i-uzel
Vyrovnávací paměť
Procesy
init PID Systémové a ostatní procesy Stavy procesů Komunikace procesů
Synchronizace procesů Semafory MUTEXy
Jádro
Služby jádra
Uživatelé
Filip Malý KIKM FIM UHK
2
Vstup uživatele do systému
Login
Password
chceme-li se přesvědčit, že je terminál stále připojen k UNIXu, stačí stisknout opět Enter (znovu se objeví login) heslo do systému (obvykle se psaný text nezobrazuje, výjimkou jsou přihlášení skrze GUI)
Shell $
Lze zadávat příkazy, znak výzvy komunikace Privilegovaný znak #
Dvě úrovně
Odhlášení lze pomocí Ctrl+d
Privilegovaná Neprivilegovaná Jiné nejsou (výjimkou SELinux)
Filip Malý KIKM FIM UHK
3
Základní schéma komunikace Komunikace pomocí příkazového řádku Jádro Program, který je zaveden po zapnutí počítače do operační paměti Program, který
Z počítače na úrovni technického vybavení vytváří virtuální počítač Odstíní uživatele od přímého styku s HW Umožňuje komunikaci se strojem ve formě vyššího programovacího jazyka Zajišťuje sdílení technických zdrojů několika uživatelům najednou
Proces je realizace akce uživatele nebo systému Procesy jsou volání jádra, pomocí kterých procesy interagují s jádrem Filip Malý KIKM FIM UHK
4
Základní schéma komunikace
Filip Malý KIKM FIM UHK
5
Soubory V UNIXu jsou soubory posloupnosti slabik bez jakékoliv další struktury Tři skupiny souborů Obyčejné soubory Adresáře Speciální soubory Každý soubor ve vnitřní struktuře reprezentován iuzlem (i-node, index node) i-uzel obsahuje všechny atributy souboru a odkazy na datovou část souboru Atributem například informace, zda je soubor obyčejným souborem nebo adresářem, či speciálním souborem, dále vlastník, přístupová práva, … Filip Malý KIKM FIM UHK
6
Soubory ls -l soubor: -rw-r----- 1 uzivatel skupina 506 datum cas jmeno_souboru První znak ve výpisu označuje typ souboru
d l c b
obyčejný soubor adresář nepřímý odkaz znakový speciální soubor blokový speciální soubor
Filip Malý KIKM FIM UHK
7
Soubory ls -l soubor: -rw-r----- 1 uzivatel skupina 506 datum cas jmeno_souboru Atributy Dalších devět znaků
r w x -
čtení dovoleno zápis dovolen soubor lze spustit (pokud je spustitelný) přístup je zakázán
Trojice práv, postupně uživatel (vlastník souboru), skupina (do které vlastník patří), ostatní uživatelé Následuje počet odkazů na soubor z různých míst systému souborů Jméno vlastníka a skupiny, Velikost souboru ve slabikách (506 znaků) Datum a čas poslední modifikace souboru Jméno souboru Filip Malý KIKM FIM UHK
8
Soubory Obyčejný soubor obsahuje data uživatele Textový soubor lze vypsat příkazem cat Binární soubor lze prohlížet příkazem od
$ od -c a.out -x mění výpis na šestnáctkovou soustavu -d soustava desítková -c znakový výpis (všechny běžně zobrazitelné znaky jsou vypsány jako znaky, ostatní v osmičkové soustavě) Bez požití volby -c zobrazuje v osmičkové soustavě Filip Malý KIKM FIM UHK
9
Soubory Adresář Binární soubor s atributem příznaku adresáře
Lze použít například na pracovní $ od -c . (nefunguje všude, některé systémy to „poznají“)
Obsahuje seznam souborů Aktuální nastavený adresář se nazývá pracovní Obsah zobrazíme pomocí ls Ve skutečnosti je to výpis i-uzlů celkem 12 drwxr-xr-x 3 fm fm 4096 2008-07-13 13:42 . drwxr-xr-x 7 fm fm 4096 2008-07-14 09:38 .. drwxr-xr-x 2 fm fm 4096 2008-04-12 10:08 temata_sypro
„Celkem 12“ informuje o celkovém obsazení souborů adresáře v blocích
Filip Malý KIKM FIM UHK
10
Soubory Adresář Hierarchická struktura adresářů
Každý adresář obsahuje nadřazený „..“ a aktuální „.“ adresář
Hierarchie završena kořenovým adresářem „/“ Aby uživatel mohl do adresáře vstoupit, musí adresář mít příslušná práva r a x mkdir, rmdir, pwd, cd, … Běžná práce se soubory cp co kam mv původní_jméno nové_jméno rm rm -i se dotazuje rm -r rekurzivně maže celý podstrom Filip Malý KIKM FIM UHK
11
Soubory Standardní vstupy, výstupy, přesměrování, filtry
Standardní vstup je vstup z klávesnice a standardní výstup je obrazovka Příkaz cat čte z klávesnice a zobrazuje na obrazovku Přesměrování do souboru s přepsáním $ cat > novytext Soubor je vytvořen a naplněn, pokud dříve existoval, je zkrácen na nulovou délku a znovu naplněn programem cat Přesměrování do souboru bez přepsání (přidání na konec) $ cat >> novytext Filip Malý KIKM FIM UHK
12
Soubory Standardní vstupy, výstupy, přesměrování, filtry
find hledá soubor dle atributů v dané části stromu adresářů
$ find . -name nejaky-soubor -print
hledá v podstromu “.“ Na standardní výstup vypisuje cesty všech souborů s relativním jménem nejaky-soubor, výpis je zajištěn pomocí -print Další příklady
$ find /usr/uzivatel -name core -exec rm {}\ rovnou maže soubory obsahující core $ find /usr -user uzivatel -type d -print vypíše všechny adresáře, které vlastní uzivatel $ find /usr/uzivatel -mtime 7 -print vypíše soubory měněné v posledních sedmi dnech$ Filip Malý KIKM FIM UHK
13
Soubory Speciální soubory Přístup k periferii výpočetního systému Standardně uloženy v podstromu /dev Příklad k přístupu k tiskárně c-w--w---- 1 bin bin 6, 0 2008-07-14 10:51 /dev/lp
Obdoba jako výpis obyčejného souboru, liší se v místě počtu slabik Zde zobrazena dvě čísla oddělená čárkou (6, 0) jsou po řadě hlavní a vedlejší číslo Hlavní číslo identifikuje zařízení (tiskárna, disk, …) Vedlejší číslo určuje specifika konkrétní periferie (například pořadí periferie, jak se bude ovládat, …) Filip Malý KIKM FIM UHK
14
Soubory Vypsat text na tiskárnu pak lze třeba takto $ cat souborstextem > /dev/lp Raději využívat spooling Tiskové úlohy řazeny za sebou do fronty typu FIFO, odkud jsou postupně odebírány a odesílány na tiskárnu operačním systémem Tisk spoolingem
$ lp souborstextem vypíše printer-123 a lze pak zrušit cancel printer-123 Pomocí příkazu s cat budou obsahy smíchány Filip Malý KIKM FIM UHK
15
Soubory
Jména speciálních souborů se řídí daným výrobcem, přesto určité standardní názvy
Přístup k periferiím znakový nebo blokový
console (operátorská konzole) clock (hodiny) fd (disketa) kmem (operační paměť jádra) lp (tiskárna) mem (operační paměť) mt (klasická magnetická páska) tty (terminál) Jde jen o základy jména, ke kterému se přidávají další dodatečné informace jako třeba číslo, pořadí, … Blokový disk Znakový terminál I s diskem však lze pracovat sekvenčně po znacích
Speciální soubor vytváří privilegovaný uživatel pomocí mknod
Filip Malý KIKM FIM UHK
16
Soubory Změna atributů
Znamená změnu dat v i-uzlu Změna vlastníka chown root soubor Změna skupiny chgrp Změna přístupových práv k souboru pomocí chmod XYZ soubor Kde XYZ jsou číselně vyjádřena práva rwx, kde se dopočítává do 7, kde r=4, w=2, x=1, takže třeba 755 = -rwx-rx-rx
$ chmod 775 soubor nebo $ chmod a+rw g+w u+w Filip Malý KIKM FIM UHK
17
Systém souborů Systém souborů realizován na magnetickém médiu Logická struktura magnetického média se nazývá svazek, neboli filesystem
Filip Malý KIKM FIM UHK
18
Systém souborů
Filip Malý KIKM FIM UHK
19
Systém souborů i-uzel (i-node, index node) Jednoznačná identifikace souboru S číslem i-uzlu spojeno jméno souboru Číslo i-uzlu je zároveň i jeho pořadí v rámci oblasti iuzlů a činí 64 slabik i-uzel obsahuje Vlastníka souboru Typ souboru Přístupová práva Datum a čas poslední manipulace se souborem Počet odkazů na soubor z různých míst stromu adresářů Tabulku datových bloků Velikost souboru Filip Malý KIKM FIM UHK
20
Systém souborů
Počet odkazů a odkazy
Pomocí nich lze k témuž souboru přistupovat z více míst systému souborů Při vytvoření souboru (například cat > sdileny) dojde k následujícímu
Pokud soubor neexistuje v daném adresáři, je vybrán první neobsazený i-uzel, souboru je přiděleno odpovídající číslo iuzlu a současně s alokací položek i-uzlu je nastaven počet odkazů na jedna
Pomocí příkazu
$ ln sdileny /home/dalsiuzivatel/sdileny
vytvoříme nový odkaz na tentýž i-uzel $ ls -i sdileny vypíše 829 sdileny a $ ls -i /home/dalsiuzivatel/sdileny by mělo vypsat stejné číslo i-uzlu, tedy 829 /home/dalsiuzivatel/sdileny Filip Malý KIKM FIM UHK
21
Systém souborů
Pokud rušíme soubor pomocí rm
Systém souborů pomocí rutin jádra prohlíží i-uzel a snižuje hodnotu odkazů o jedničku dolů
Pomocí ln odkazy v rámci jednoho svazku Odkazy na jiné svazky pomocí přepínače –s
Je-li po této dekrementaci počet odkazů vyšší než nula, systém pouze rozpojí vazbu „jméno souboru – i-uzel“ Je-li ale hodnota nulová, je i-uzel uvolněn ze seznamu alokovaných a převeden do seznamu volných, datový obsah souboru pak zaniká a zaniká celý soubor
Vytváříme nepřímé odkazy, které při výpisu adresáře poznáme podle prvního písmene l Nepřímý odkaz realizován tak, že i-uzel má příznak a v datové části se nachází cesta k souboru na jiném svazku Jsou-li svazky jinak připojeny, mohou symbolické odkazy odkazovat na neplatná místa, tzn. nevedou nikam
Odkazy mohou být tvořeny i na adresáře, obvykle ale pouze privilegovaný uživatel má k tomuto práva
Filip Malý KIKM FIM UHK
22
Systém souborů Tabulka datových bloků v i-uzlu Prvních 10 hodnot (0-9) odkazují na datové bloky 11. hodnota je odkaz na blok nepřímé reference Tzn. odkazovaný blok obsahuje vlastní odkazy na datové bloky Po vyčerpání je 12. hodnota odkaz na blok druhé nepřímé reference (odkaz na blok odkazující na bloky teprve s referencí na data), po vyčerpání 13. hodnota... Filip Malý KIKM FIM UHK
23
Systém souborů
Filip Malý KIKM FIM UHK
24
Systém souborů
Blok popisu svazku super block obsahuje následující informace
Velikost svazku Počet volných datových bloků svazku Seznam neobsazených datových bloků svazku Ukazatel na první neobsazený blok v seznamu volných svazků Velikost oblasti i-uzlů Počet neobsazených i-uzlů svazku Seznam volných i-uzlů svazku Ukazatel na první neobsazený i-uzel Pole zámků pro neobsazené datové bloky a neobsazené i-uzly Příznak modifikace bloku popisu svazku
Svazky se připojují do hierarchie svazku s kořenovým adresářem /
Jednotlivé svazky lze připojovat pomocí mount
Novější filesystémy mají efektivnější způsoby práce s daty
Jiný počet bloků Mapy skupiny cylindrů Větší délka i-uzlů a více přímých odkazů na data v i-uzlu … Filip Malý KIKM FIM UHK
25
Vyrovnávací paměť
Mezi jádrem a systémem souborů systémová vyrovnávací paměť UNIX předpokládá sekvenční přístup k datům, proto je následující blok dat již při čtení předchozího připraven ve vyrovnávací paměti Malá velikost zpomaluje a zbytečně brzdí systém i uživatele Velká velikost naopak zbytečně ukrajuje část operační paměti Uložení vyrovnávací paměti pomocí sync
Za normálního chodu dělá sám systém obvykle každých 30 sekund (dle nastavení systému)
Přímý přístup k datům
Programově lze pomocí lseek přesouvat pozici čtení nebo zápisu v otevřeném souboru na různé pozice – zefektivnění práce aplikace s daty s pevnou délkou formátu
Filip Malý KIKM FIM UHK
26
Procesy Tvoří hierarchickou strukturu Po startu OS, tj. startu jádra vzniká proces id 0 nazývaný swapper (nebo sched) Hlavním smyslem je pracovat pro údržbu správy paměti Ihned na začátku vytváří proces s init id 1 pomocí odkazu na jádro Proces vzniklý odkazem na jádro z jiného procesu je proces synovský / dceřiný (child) vzhledem k procesu, který jej vytvořil (otec, rodič, parent) Žádosti o vznik dalšího procesu říkáme fork (rozvětvení) a proces jej uplatní pomocí volání jádra fork Filip Malý KIKM FIM UHK
27
Procesy
Proces init je otcem dalších procesů
Udržuje několik úrovní stavu systému, kde každá úroveň reprezentována množinou procesů, které init vytváří a dohlíží na jejich stav
hlavní dvě úrovně: jednouživatelská a víceuživatelská
pak například $ cat soubor je interpretován procesem sh vytvořením nového procesu pomocí volání jádra fork se jménem cat, sh je tedy rodičem procesu cat
Single user – init vytváří jen úroveň pro údržbu systému a celkové změny v systému Multi user – standardní běh systému init vytváří proces getty pro přihlášení a vstup uživatele do systému Procesy getty mají jednoznačnou identifikaci přidělenou jádrem Proces getty se v případě úspěšného přihlášení mění na proces sh, který realizuje běžnou komunikaci uživatele se systémem, říkáme mu příkazový shell
Filip Malý KIKM FIM UHK
28
Procesy init vytváří další procesy: například update (aktualizace dat ve vyrovnávací paměti), lpsched (spooling tiskárny), … tyto procesy běží obvykle v nekonečné smyčce a slouží k zajištění určitých akcí na základě nějaké události, probouzí se obvykle na základě časového limitu nebo pokynu jádra takovým procesům říkáme démoni
Identifikační číslo procesu PID Jednoznačné odlišení a identifikace procesu Celé kladné číslo přidělené podle naposledy vznikajícího procesu zvýšené o jedničku Pokud je dosažena nejvyšší hodnota, začíná jádro od nuly, přitom však vynechává ta čísla, která jsou již obsazena aktivními procesy Filip Malý KIKM FIM UHK
29
Procesy Procesy systémové a ostatní
init, swapper = systémové procesy – jsou systémem zvýhodněné sh, cat = ostatní procesy Zvýhodnění zejména ve stanovení dynamické priority – číselná hodnota, podle které se přiděluje čas procesoru Priorita procesu je vypočtena při vzniku procesu z tzv. uživatelské priority, což je celé kladné číslo obvykle z intervalu 0 – 39 (menší hodnota = vyšší priorita) a z času procesu v systému Dynamická priorita se procesům vypočítává obvykle po uplynutí každé sekundy, anebo na základě interakce procesu s jádrem Filip Malý KIKM FIM UHK
30
Procesy Interakce z terminálu obvykle znamená zpracování vstupu jádrem, proto jsou zvýhodňovány procesy podporující práci u terminálu – odtud interaktivní operační systém Hranice priority mezi systémovými a ostatními procesy je hodnota 20, žádný obyčejný proces by neměl mít prioritu menší než 20 – tím je co nejvíce zajištěna průchodnost systému a ochrana proti zahlcení Výchozí hodnota při spuštění procesu je 20 $ nice -5 find / -name core -print > findcore znamená, že příkaz find bude proveden s prioritou 25 Uvedeme-li jen $ nice find … bude priorita rovna hodnotě 30 Filip Malý KIKM FIM UHK
31
Procesy Než je procesu přidělen procesorový čas, musí být zaveden do operační paměti Jakmile je proces vytvořen, snahou jádra je přidělit mu požadovanou paměť Není-li dostatek paměti, uplatní jádro na procesy v paměti algoritmy se snahou odsunout některé procesy mimo paměť – jádro se zde orientuje podle času, který proces v paměti již strávil – proces nejdéle sídlící v paměti je odsunut
Odsouvání z paměti swap out a zavlékání do paměti swap in se provádí na/z místa nazývaného jako odkládací prostor swap area Odkládací oblast je dána parametry jádra a je situována na disk, ale mimo jakýkoliv svazek systému souborů
Swapování má na starosti proces s id 0 swapper
Filip Malý KIKM FIM UHK
32
Procesy Stavy procesu Volání jádra pro vytvoření procesu fork Neaktivní čekání procesu sleep Ukončení procesu exit Po žádosti o ukončení procesu může proces přejít do stavu zombie, neboli mátoha Proces, který ještě nebyl jádrem zrušen, ale v co nejkratší době tak jádro učiní (ještě nebyly zrušeny všechny odpovídající položky v tabulkách jádra)
Filip Malý KIKM FIM UHK
33
P r o c e s y Filip Malý KIKM FIM UHK
34
Procesy Odkládací prostor Uživatel může odkládací prostor využít pro zefektivnění spuštění opakovaného procesu pomocí tzv. sticky bitu (t-bit)
$ chmod u+t aplikace způsobí, že po ukončení procesu aplikace bude obsahu „okopírován“ do odkládacího prostoru a toto umístění si jádro zaznamená při opětovném spuštění využije jádro místo v odkládací paměti a aplikace se tak spustí rychleji Filip Malý KIKM FIM UHK
35
Procesy
Uživatel přihlášený do systému je vlastníkem všech procesů, které interaktivně spustil
Uživatel může spustit aplikaci, která ale vyžaduje ke svému „správnému“ běhu privilegovaná práva, pak lze aplikaci přidělit práva pomocí tzv. s-bitu
# chmod g,o+s soubor uživatel je v akci regulován programem, který vlastní superuživatel
Proces je v době běhu rozdělen na tři základní části
Textový segment obsahuje instrukce programu Datový segment obsahuje datové struktury programu Zásobník Není-li řečeno jinak, je textový segment považován za část, která není v době běhu procesu měnitelná, takže při spuštění několika procesů s odkazem na tentýž program
Sdílejí běžící procesy stejný textový segment Žádají přidělení paměti jen pro datový segment a zásobník Filip Malý KIKM FIM UHK
36
Procesy
Procesy jsou sdružovány do skupin, tzv. rodiny procesů
Každý proces má právo pomocí volání jádra setpgrp za vedoucího skupiny (otce rodiny) a tím se osamostatnit od rodiny, do které dosud patřil Každý shell se po přihlášení prohlašuje za otce rodiny a všechny procesy (synové) jsou s ním existenčně spjati Ukončí-li otec rodiny svou činnost, zanikají všichni jeho synové (pokud nejsou v supervizorovém stavu) Příklad
$ gcc -o program velkyprogram.c & způsobí, že proces běží a uživatel může dále zadávat další příkazy (vytvářet další procesy)
Pokud se však uživatel odhlásí, bude násilně ukončen i překlad programu
Syna prohlásíme za samostatného pomocí
$ nohup gcc -o program velkyprogram.c & a v případě odhlášení uživatele tento proces poběží dál až do svého zdárného konce
Filip Malý KIKM FIM UHK
37
Procesy Komunikace procesů na základní úrovni
Je zajištěna pomocí zasílání signálů Signály jsou číslovány od jedničky Zaslání signálu dříve znamenalo ukončení procesu, dnes obvykle proces signál obdrží a může provést nějakou činnost a pak se vrátit ke své běžné činnosti může signál ignorovat, případně provést nějakou svou akci a pak se ukončit – závisí na způsobu použití volání jádra signal Proces zasílá jinému procesu signál voláním jádra kill, musí znát jeho PID Filip Malý KIKM FIM UHK
38
Procesy
Komunikace dvou procesů na úrovni dat
pomocí roury (pipe) dle schématu producent | konzument, například $ ls | wc -l Standardní výstup producenta je přepnut do části paměti pro rouru a standardní vstup konzumenta je přepnut do téže oblasti paměti jako proces, který data z roury čte Jádro zajistí pozastavení procesu producent, je-li roura plná, anebo procesu konzument, je-li roura prázdná Producent uzavírá rouru znakem konce souboru (Ctrl+d) a konzument po přečtení konce souboru také, čímž roura zaniká Komunikace pomocí roura omezena na procesy, které jsou v přímém příbuzenském vztahu – nemohou takto tedy spolu komunikovat procesy různých uživatelů – toto a další problémy řeší IPC Inter Process Communication
V rámci IPC je možné vytvářet pojmenovanou rouru, kdy je taková roura vytvořena trvale a spojena se soubory zvláštního typu V rámci IPC také mohou dva libovolné procesy sdílet data, spolupracovat na základě předávání zpráv a mohou využívat tzv. Dijkstrových semaforů Filip Malý KIKM FIM UHK
39
Procesy Nepojmenované roury Z příkazového řádku se provede operátorem | Vytvářejí se systémovým voláním pipe, které vrátí dva deskriptory Pro čtení Pro zápis
Deskriptory roury jsou při vytváření procesů děděné, do roury může zapisovat a číst z ní více procesů, přičemž data jsou čtena v pořadí v jakém byla zapsána Procesy můžou komunikovat prostřednictvím roury, byla-li vytvořena společným předchůdcem, po skončení všech procesů roura přestává existovat, zaniká Filip Malý KIKM FIM UHK
40
Procesy
Pojmenované roury, FIFO soubory – mezi nepříbuznými procesy – systém IPC
Jsou perzistentní, existují jako soubory, i když je nepoužívají žádné procesy FIFO musí být explicitně zrušen, jako obyčejné soubory – unlink Na rozdíl od obyčejných souborů přečtená data jsou odstraněna a z pohledu komunikace mají stejnou sémantiku jako nepojmenované roury Vytvoření FIFO souboru
mknode (cesta, mód, zařízení) mkfifo (cesta, mód)
mód obsahuje obvyklá oprávnění v případě mknode obsahuje disjunkci S_IFIFO a oprávnění třetí parametr slouží pro vytváření speciálních souborů pro zařízení
FIFO jsou potom jako obvykle otevřena systémovým voláním open, které vrátí deskriptor souboru a do FIFO můžeme zapisovat systémovým voláním write, anebo z něho číst systémovým voláním read
Filip Malý KIKM FIM UHK
41
Procesy
Možnosti předávání dat mezi procesy
Pojmenovaná roura named pipe – FIFO Fronty zpráv – jádro spravuje oblast zpráv
Sdílená paměť
Obdobný princip jako u předešlého – jádro spravuje datovou paměť, jejíž oblast lze přidělit podle „klíče“ – možnost pro více procesů sdílet společná data (připojení, vytvoření,...) Volání jádra shmat, shmget, ....
Semafory
Přístup procesů k určité frontě pomocí „klíče“ – princip „producent – konzument“ Volání jádra msgsnd, msgget, ...
Umožňuje získat exkluzivní (synchronizovaný) přístup k datům pro skupinu procesů bez rizika uváznutí Volání jádra semop, semget, ....
BSD sockety
Pro síťovou komunikaci mezi procesy běžícími na vzdálených systémech – princip klient – server, kde server je implementován procesem typu démon
Filip Malý KIKM FIM UHK
42
Procesy Měli bychom zavírat nadbytečné deskriptory souborů Vykonáváním fork a exec získávají nezavřené deskriptory souborů další procesy a v nich vykonávané programy read z roury vrátí konec souboru jenom tehdy, není-li otevřená pro zápis Šetříme
Filip Malý KIKM FIM UHK
43
Synchronizace procesů Zajištění výlučného přístupu k systémovým zdrojům Příklady strategie Zámky Semafory (přístup k datům) Spooling (organizace tisku)
Meziprocesová komunikace Meziprocesové zprávy Organizace front zpráv Filip Malý KIKM FIM UHK
44
Synchronizace procesů
Semafory – MUTEXy
Základní prostředky operačního systému k realizaci vzájemného vyloučení (MUTual EXclusion) Princip
Semafor je celočíselná nezáporná proměnná s hodnotou N Nad semaforem provádějí atomické operace funkce wait (snižuje hodnotu N o 1) a signal (zvyšuje hodnotu N o 1) Hodnotu semaforu N nastavuje inicializační operace init Před vstupem do kritické oblasti sníží proces funkcí wait hodnotu N o 1
Je-li N = 0, proces je pozastaven a zařazen do fronty semaforu Je-li N > 0, proces uzavírá zdroj
Bylo-li N = 0, vybere se z fronty semafory zablokovaný proces a „probudí se“...
Před výstupem z kritické oblasti funkce signal zvýší N o 1
Služba semaforů je implementovaná v jádře
Filip Malý KIKM FIM UHK
45
Jádro
Jádro (neboli kernel) je programové vybavení, které pracuje na počítači bez jakékoliv další programové podpory, představuje množinu obslužných programů trvale umístěných v paměti, k nimž má každý proces přístup, základem operačního systému a odpovídá za správu všech hardwarových prostředků počítače, jako jsou disky, síťová rozhraní atd. Na rozdíl od systému MS Windows neobsahuje jádro GNU/Linuxu žádné knihovny na aplikační úrovni ani grafické uživatelské rozhraní Je velkým rozhraním mezi uživatelem a technickým vybavením počítače Udržuje a podporuje v činnosti systém souborů a běžící procesy Zajišťuje realizaci odkazů uživatelů nebo procesů na periferie Filip Malý KIKM FIM UHK
46
J á d r o
Filip Malý KIKM FIM UHK
47
Jádro Uživatelská úroveň je jádrem podporována přes rozhraní volání jádra, neboli program používá volání funkce, která je voláním jádra a program tak vstupuje do režimu obsluhy jádrem (proces vstupuje do supervizorské úrovně) Činnost jádra v okamžiku, kdy zajišťuje určitou akci vyžádanou procesem, je jiným procesem nepřerušitelná
Filip Malý KIKM FIM UHK
48
Jádro Obslužné programy jádra systému mohou být volány několika způsoby Systémové volání system call Zajistí aktivaci určitého kódu jádra jménem volajícího procesu, například volání read přečte data z deskriptoru souboru Obsluha přerušení interrupt handler Když určitý proces vykonává činnost, při níž se dostane do stavu čekání (například čtení dat z klávesnice), uvede jádro tento proces do stavu spánku (sleep) a místo něj aktivuje jiný proces, který přerušení obslouží Filip Malý KIKM FIM UHK
49
Jádro
Interní rutiny
Správa a přidělování paměti swapping Sdílení času procesoru systém priorit Vazba na technické prostředky – ovladače – rutiny
Obsazení zařízení – při inicializaci jádra Přerušení – při obdržení zprávy přerušení od zařízení Otevírání / uzavírání souboru – od systémového volání při obsazení / uvolnění zařízení procesem Přenosy (datové rutiny) – od systémového volání - žádost o natažení / uložení dat Ostatní nedatové – řízení činnosti a operací určitého I/O zařízení
Systémové služby
Realizace služby požadované externím uživatelem (procesem) pomocí systémového volání nebo knihovních funkcí
Filip Malý KIKM FIM UHK
50
Jádro Jádro dále Vykonává služby Zpracovává výjimky (pokus dělit nulou, přetečení uživatelského zásobníku, …) Zpracovává přerušení od periferních zařízení Vykonává systémové procesy (správa paměti, přepočítávaní priorit procesů, …) … Filip Malý KIKM FIM UHK
51
Služby jádra v OS GNU/Linux Jádro OS GNU/Linux = Linux Označováno někdy za monolitické – ovladače zařízení jsou součástí jádra Jiné OS používají architekturu tzv. mikrojádra (Singularity, Midori), v níž ovladače zařízení a další obslužné programy jsou do paměti zaváděny až podle potřeby a nejsou nutně v RAM přítomny Linux však podporuje i tzv. zaváděné ovladače zařízení, které mohou být zavedeny do paměti nebo z ní odstraněny prostřednictvím příkazu uživatele Proto je někdy jádro označováno za hybridní = kombinace monolitického a mikrojádra Jádro umožňuje využívat speciálních vlastností chráněného módu procesorů Intel (od 80386), zejména pro správu paměti v chráněném módu Filip Malý KIKM FIM UHK
52
Služby jádra v OS GNU/Linux Podporuje tzv. pravý hardwarový paralelismus, kdy jednotlivá vlákna jádra mohou běžet současně na více procesorech Stránkování na vyžádání (on pageing demand) Z disku zavádí pouze ty segmenty programu, které jsou zrovna aktivní Pokud je jeden program spuštěn vícekrát, je v paměti umístěna pouze jedna jeho kopie Sdílené dynamické knihovny DLL – knihovní moduly jsou zaváděny do paměti až dynamicky za běhu programu a programy mohou sdílet společný kód uložený v jedné knihovně umístěné na disku (úspora paměti i disku) Filip Malý KIKM FIM UHK
53
Služby jádra v OS GNU/Linux
Virtuální paměť se stránkováním do tzv. odkládacího prostoru swap space
Cachování diskového přístupu
Jakmile aplikace potřebují více fyzické paměti, než kolik je v počítači momentálně fyzicky nainstalováno, odloží do tohoto prostoru neaktivní stránky operační paměti (paměťová stránka má standardně velikost 4 KB), při opakovaném přístupu ke stránkám se data načtou z disku zpět do hlavní operační paměti Snaha vyhýbat se relativně pomalému přístupu k disku udržováním těch částí souborů v paměti, k nimž procesor nedávno přistupoval Jádro k tomu využívá veškerou volnou fyzickou paměť
Ukládání obsahu paměti na disk core dump
U programu, který provedl neplatnou operaci (například přístup k neplatnému místu v paměti Výpis se promítne do souboru core v adresáři, kde inkriminovaný program běžel Filip Malý KIKM FIM UHK
54
Verze jádra
Jádro má svoje vlastní číslo verze Verze jádra je označena třemi čísly ve formátu X.Y.Z
X je hlavní číslo (major) Y je vedlejší číslo (minor) Z představuje tzv. patch level – verze oprav chyb a bezpečnostních záplat
V libovolném daném okamžiku existují dvě nejaktuálnější verze jádra (Unix)
Stabilní verze (stable)
Určena pro běžné uživatele systému, kteří nehodlají systém měnit a provádět časté kompilace jádra Verze je číslována vždy sudým číslem na konci, například 2.4
Velice rychle se mění a není vždy zaručena plná funkčnost Ukončena vedlejším lichým číslem, například 2.5
Vývojová verze
V Linuxu toto neplatí, úvaha o změně číslování dle roků Filip Malý KIKM FIM UHK
55
Uživatelé
Uživatel reprezentován
Akcemi, které vykonává pomocí skupiny procesů Staticky pak všemi soubory, které vlastní
Registrace uživatele v tabulkách souborů /etc/passwd, /etc/group, /etc/shadow, … fm:x:1001:1001:fm,,,,:/home/fm:/bin/bash Položky
Login Heslo (dnes nahrazeno znakem „x“ nebo „*“ a obvykle obsaženo v /etc/shadow) Id uživatele jedinečné z hlediska instalace systému (nachází se například v i-uzlech souborů, které uživatel vlastní) Id skupiny (koresponduje s /etc/group) Komentář Cesta k domovskému adresáři Cesta k programu, který bude spuštěn při přihlášení jako příkazový interpret Filip Malý KIKM FIM UHK
56
Subsystém souborů
Obsah prezentace Struktura souborů v UNIXu Soubory a zařízení Systémová volání a ovladače zařízení Knihovní funkce Nízkoúrovňový přístup k souborům Další systémová volání pro správu souborů
Standardní V/V knihovna Formátovaný vstup a výstup Další funkce pro práci s proudy Chyby proudu Údržba souborů a adresářů Procházení adresářů
Filip Malý KIKM FIM UHK
2
Struktura souborů v UNIXu Téměř vše je soubor Základní funkce
open close read write ioctl
Čtení adresářů opendir / readdir – vysokoúrovňové rozhraní
Filip Malý KIKM FIM UHK
3
Soubory a zařízení I HW zařízení často reprezentována jako soubory /dev/console Reprezentuje systémovou konzoli, na kterou jsou posílány chybové zprávy a diagnostická hlášení /dev/tty Zástupcem pro řídicí terminál (klávesnici a obrazovku nebo okno) procesu /dev/null Nulové zařízení, veškerý výstup na něj odeslaný bude zrušen $ cp /dev/null prazdny_soubor /dev/zero Pro tvorbu nulových souborů
Filip Malý KIKM FIM UHK
4
Systémová volání a ovladače zařízení K souborům a zařízením můžeme přistupovat pomocí malého počtu funkcí Tyto funkce se nazývají systémová volání a tvoří tak vlastní rozhraní operačního systému Aby bylo možné pomocí ovladačů obhospodařovat HW, shrnují všechny funkce závislé na HW, charakteristické rysy HW pak zpřístupněny pomocí systémového volání ioctl Stejná funkce pro přístup k normálnímu souboru se použije i pro přístup k tiskárně, uživatelově terminálu, …
Filip Malý KIKM FIM UHK
5
Systémová volání a ovladače zařízení Nízkoúrovňové funkce pro přístup k ovladačům HW, tzv. systémová volání open otevře soubor nebo zařízení read čte ze souboru nebo zařízení write zapisuje do souboru nebo zařízení close zavře soubor nebo zařízení ioctl předá řídicí informace ovladači zařízení ioctl poskytuje některé nezbytné řízení specifické pro daný HW (protikladem normální vstup a výstup) Jeho použití se liší v závislosti na zařízení, a proto nemusí být takové volání přenositelné mezi počítači Každý ovladač definuje vlastní sadu příkazů ioctl
Filip Malý KIKM FIM UHK
6
Knihovní funkce Nízkoúrovňová systémová volání nejsou příliš efektivní
Dochází ke snížení výkonu Systém neustále musí přepínat mezi běžícím programem a kódem jádra HW má určitá omezení, což může klást omezení na velikost bloků dat, které je možné systémovým voláním číst nebo zapisovat Pokud má zařízení nejmenší jednotku zápisu 10 KB a my zapíšeme pomocí systémového volání menší objem dat, zařízení stejně posune záznamovou hlavu o 10KB, takže budou vznikat mezery
Filip Malý KIKM FIM UHK
7
Knihovní funkce UNIX ovšem poskytuje řadu standardních knihoven
Zajišťují propracovanější rozhraní pro zařízení a diskové soubory Jsou to sbírky funkcí, které lze začlenit do vytvářených programů Například standardní V/V knihovna poskytující výstup přes vyrovnávací paměť Pomocí ní lze zapisovat různé bloky dat různých velikostí a knihovna sama zařídí, aby systémové volání mělo vždy k dispozici plné bloky dat – výrazně sníží režii systémových volání stdio.h Filip Malý KIKM FIM UHK
8
Knihovní funkce
Filip Malý KIKM FIM UHK
9
Nízkoúrovňový přístup k souborům Každý proces má přidruženo několik deskriptorů souboru Malá celá čísla, která lze používat při přístupu k otevřeným souborům nebo zařízením
Spuštěný program má obvykle otevřeny následující deskriptory 0 standardní vstup 1 standardní výstup 2 standardní chybový výstup
Filip Malý KIKM FIM UHK
10
Nízkoúrovňový přístup k souborům write #include size_t write (int fildes, const void *buf, size_t nbytes);
Systémové volání write zajistí zapsání n bajtů (nbytes) z proměnné buf do souboru sdruženého s deskriptorem fildes Vrací počet skutečně zapsaných bajtů 0 = nic nebylo zapsáno -1 = došlo k chybě a chyba bude specifikována v globální proměnné errno Pokud write zahlásí menší počet bajtů, než jsme měli v plánu, nemusí se jednat o chybu Nutné kontrolovat errno a je-li to nutné, zavolat znovu zápis, aby se zapsala všechna zbývající data Filip Malý KIKM FIM UHK
11
Nízkoúrovňový přístup k souborům read #include size_t read (int fildes, const void *buf, size_t nbytes);
read přečte n bajtů (nbytes) dat ze sdruženého s deskriptorem fildes a umístí je do datové oblasti buf Vrací počet skutečně přečtených bajtů dat, který může být menší, než bylo požadováno Vrací 0 = nebylo již co číst a bylo dosaženo konce souboru -1 = došlo k chybě Filip Malý KIKM FIM UHK
12
Nízkoúrovňový přístup k souborům open…
Pokud chceme vytvořit nový deskriptor souboru, musíme použít systémové volání open #include #include <sys/types.h> /* hlavičky sys/ se mohou hodit na NE-POSIX systémech */ #include <sys/stat.h> int open (const char *path, int oflags); int open (const char *path, int oflags, mode_t mode); open zajistí přístupovou cestu k souboru nebo zařízení
V případě úspěchu vrací deskriptor souboru, který pak lze použít pro read nebo write Deskriptor je jedinečný a není sdílen žádným jiným běžícím procesem Je-li otevřen jeden soubor vícekrát odlišnými programy, každý si udržuje jiný deskriptor (oba mohou zapisovat tam, kde skončily, nedochází však k proložení dat, ale k přepisu – lze zabránit zamykáním souborů) Filip Malý KIKM FIM UHK 13
Nízkoúrovňový přístup k souborům …open
Název souboru či zařízení je předán v parametru path a akce, které lze s otevřeným souborem provádět, specifikuje oflags
Ten specifikován jako bitové OR
a dalších nepovinných
Povinného režimu přístupu k souboru (O_RDONLY, O_WRONLY, O_RDWR) O_APPEND – umístí data na konec souboru O_TRUNC – nastaví nulovou délku a původní obsah zruší O_CREAT – dle potřeby vytvoří soubor s právy předanými v parametru mode O_EXCL – použití společně s O_CREAT a zajišťuje vytvoření souboru volajícím programem – zajistí, aby tentýž soubor nevytvořily dva programy současně
V případě úspěchu je deskriptor vždy celé kladné číslo, pokud dojde k neúspěchu, vrací -1 Filip Malý KIKM FIM UHK
14
Nízkoúrovňový přístup k souborům umask
Není systémové volání, ale systémová proměnná Definuje masku přístupových práv, která se mají použít při tvorbě nového souboru
close
#include int close (int fildes)
Systémové volání slouží k přerušení spojení mezi deskriptorem souboru a jeho souborem, takže deskriptor souboru je pak možné znovu použít Úspěch vrací 0, chyba vrací -1
ioctl #include int ioctl (int fildes, int cmd, ...) Filip Malý KIKM FIM UHK
15
Další systémová volání pro správu souborů lseek
Nastavuje hodnotu čtení nebo zápisu deskriptoru souboru fildes tak, že můžeme určit, kde bude pokračovat čtení nebo zápis, lze nastavovat absolutně nebo relativně #include #include <sys/types.h> off_t lseek (int fildes, off_t offset, int whence)
offset specifikuje pozici whence udává jakým způsobem bude offset použit
SEEK_SET offset je absolutní pozice SEEK_CUR relativní k aktuální pozici SEEK_END relativní vzhledem ke konci souboru
Vrací
offset měřený v bajtech od začátku souboru -1 při chybě Filip Malý KIKM FIM UHK
16
Další systémová volání pro správu souborů fsat, stat, lstat Vrací informace o souboru spojeným s deskriptorem
dup, dup2 Duplikace deskriptoru souboru, lze tak získat více deskriptorů a pomocí nich přistupovat do různých částí jednoho souboru
Filip Malý KIKM FIM UHK
17
Standardní V/V knihovna Hlavičkový soubor stdio.h Poskytuje univerzální rozhraní pro nízkoúrovňová V/V systémová volání Při otevření souboru otevřeny tři proudy (odpovídají deskriptorům 0, 1 a 2) stdin stdout stderr
Ekvivalent nízkoúrovňového deskriptoru se nazývá stream (proud) a je implementován jako ukazatel na strukturu FILE * Filip Malý KIKM FIM UHK
18
Standardní V/V knihovna fopen… #include <stdio.h> FILE *fopen (const char *filename, const char *mode);
Je analogií pro open Používá se především pro souborový a terminálový vstup a výstup Používá vyrovnávací paměť fopen otevře soubor filename a sdruží s ním proud
Filip Malý KIKM FIM UHK
19
Standardní V/V knihovna …fopen mode definuje způsob otevření souboru r nebo rb – otevření pro čtení w nebo wb – zápis a zkrácení souboru na nulovou délku a nebo abv – zápis s připojením na konec souboru r+ nebo rb+ nebo r+b – otevření pro zápis i čtení (aktualizace) obdobně pro w+ nebo a+ b specifikuje, že jde o binární a nikoliv textový soubor Režim přístupu musí být řetězec, tj. “r“ a nikoliv 'r' Filip Malý KIKM FIM UHK
20
Standardní V/V knihovna fread #include <stdio.h> size_t fread (void *ptr, size_t size, size_t nitems, FILE* stream);
Slouží ke čtení dat ze souborového streamu size velikost záznamu nitems počet záznamů, které mají být načteny Vrací počet položek (nikoliv bajtů), které se podařilo načíst
Filip Malý KIKM FIM UHK
21
Standardní V/V knihovna fwrite #include <stdio.h> size_t fwrite (const void *ptr, size_t size, size_t nitems, FILE* stream);
Obdoba fread
fclose #include <stdio.h> int fclose(FILE *stream);
Zavře specifikovaný proud, způsobí zapsání nezapsaných dat = nutné používat Filip Malý KIKM FIM UHK
22
Standardní V/V knihovna fflush #include <stdio.h> int fflush (FILE *stream);
Zajistí okamžité zapsání všech nevyřízených dat v souborovém proudu
fseek
#include <stdio.h> int fsekk (FILE *stream, long int offset, int whence);
Je ekvivalentem systémového volání lseek
offset specifikuje pozici, whence udává jakým způsobem bude offset použit, viz lseek
Nastavuje pozici pro příští čtení nebo zápis fseek však vrací celé číslo
0 úspěch -1 neúspěch
Filip Malý KIKM FIM UHK
23
Standardní V/V knihovna fgetc, getc, getchar Vrací další bajt, konec souboru nebo chyba – vrací EOF
fputc, putc, putchar Zapíše znak do výstupního souborového proudu
fgets, gets Čte řetězec ze vstupního proudu stream
Filip Malý KIKM FIM UHK
24
Formátovaný vstup a výstup printf, fprintf, sprintf… #include <stdio.h> int printf (const char *format, …); int sprintf (char *s, const char *format, …); int fprintf (FILE *stream, const char *format, …); Formátuje a posílá na výstup proměnný počet argumentů různých typů format řídí, jakým způsobem budou argumenty reprezentovány ve výstupním proudu format je tedy řetězec, který se má vytisknout, obsahující ještě kódy, tzv. konverzní specifikátory Ty udávají, jak mají a kde mají být zbylé argumenty vytištěny Filip Malý KIKM FIM UHK
25
Formátovaný vstup a výstup …printf, fprintf, sprintf… printf zapisuje na standardní výstup fprintf zapisuje do souboru (do specifikovaného proudu stream) sprintf zapisuje svůj výstup včetně ukončovacího nulového znaku do řetězce předaného jako parametr printf(“Nějaká čísla: %d, %d a %d\n“, 1, 2, 3); a výstupem je řetězec Nějaká čísla: 1, 2 a 3 Filip Malý KIKM FIM UHK
26
Formátovaný vstup a výstup …printf, fprintf, sprintf… Konverzní specifikátory %d, %i vytiskne číslo v desítkové soustavě %o, %x osmičková a šestnáctková soustava %c znak %s řetězec %f číslo s plovoucí desetinnou čárkou (s jednoduchou přesností) %e jako %f ale s dvojnásobnou přesností %g číslo typu double v obecném formátu
Filip Malý KIKM FIM UHK
27
Formátovaný vstup a výstup …printf, fprintf, sprintf Počet a typ argumentů musí odpovídat konverzním specifikátorům Specifikátory polí Uvádějí se bezprostředně po znaku % Specifikují počet mezer nebo desetinných míst, která mají být vytištěna Například %10.4F pro 12.34 odpovídá 12.3400
Funkce vracejí počet zapsaných znaků sprintf nezapočítává koncový znak null Filip Malý KIKM FIM UHK
28
Formátovaný vstup a výstup scanf, fscanf, sscanf… #include... int scanff (const char *format, …); int fscanf (FILE *stream, const char *format, …); int sscanf (char *s, const char *format, …); Funguje podobně jako printf, ale čte z proudu a ukládá hodnoty do proměnných na adresy, které jsou předány jako parametry Proměnné a hodnoty musí být stejného typu, jinak může dojít k porušení paměti a program havaruje
Filip Malý KIKM FIM UHK
29
Formátovaný vstup a výstup …scanf, fscanf, sscanf… Opět existují konverzní specifikátory, normální znaky však specifikují znaky, které musí vstup obsahovat int num; scanf(“Ahoj %d“, %num); Bude úspěšné jen tehdy, pokud následující čtyři znaky standardního vstupu bude tvořit posloupnost Ahoj, dále bude načteno číslo Mezera ve formátovacím řetězci udává, že se má ignorovat bílé místo (mezery, taby, …) Filip Malý KIKM FIM UHK
30
Formátovaný vstup a výstup …scanf, fscanf, sscanf Konverzní specifikátory %d načte desítkové celé číslo %o, %x osmičkové, šestnáctkové číslo %f, %e, %g číslo s pohyblivou desetinnou čárkou %c znak (nepřeskakuje bílé místo) %s řetězec %[] množina znaků %% načte znak % Filip Malý KIKM FIM UHK
31
Další funkce pro práci s proudy fgetpos Zjistí aktuální pozici v souborovém proudu
fsetpos Nastaví aktuální pozici v souborovém proudu
ftell Vrátí aktuální offset souboru v proudu
rewind Vynuluje pozici v proudu
Filip Malý KIKM FIM UHK
32
Další funkce pro práci s proudy freopen Znovu použije souborový proud
setvbuf Nastaví vyrovnávací paměť pro proud
remove Ekvivalentní funkci unlink s výjimkou případu, kdy je parametr path adresářem, pak se jedná o ekvivalent funkce rmdir
Filip Malý KIKM FIM UHK
33
Chyby proudu Funkce knihovny stdio vrací při chybě hodnoty mimo rozsah Pak je chyba uvedena v externí proměnné errno # include <errno.h> extern int errno;
Hodnota proměnné je platná po selhání příslušné funkce, dokud její hodnotu nezmění jiná selhající funkce Z proudu lze zjistit, zda došlo k chybě nebo bylo dosaženo konce souboru Filip Malý KIKM FIM UHK
34
Chyby proudu #include <stdio.h> int ferror (FILE *stream); inf feof (FILE *stream); int clearerr (FILE *stream); ferror Testuje chybový indikátor proudu a je-li nastaven, vrací nenulovou hodnotu, v opačném případě vrací nulu
Filip Malý KIKM FIM UHK
35
Chyby proudu feof
Testuje indikátor konce souboru v rámci proudu a je-li nastaven, vrací nenulovou hodnotu, jinak vrací nulu if (feof(nejaky_proud)) /* jsme na konci */
clearerr
Vynuluje indikátor konce souboru a chybový indikátor proudu, na který ukazuje proměnná stream Nemá žádnou návratovou hodnotu a nejsou definovány žádné chyby
fileno
int fileno(FILE *stream); Umožňuje zjistit, který nízkoúrovňový deskriptor souboru je pro daný souborový proud používán Filip Malý KIKM FIM UHK
36
Údržba souborů a adresářů chmod Změna přístupových práv k souboru nebo adresáři #include <sys/stat.h> int chmod(const char *path, mode_t mode); Režimy přístupu jsou stejné jako u volání funkce open
chown Změna vlastníka superuživatelem #include <sys/stat.h> int chown (const char *path, uid_t owner, gid_t group);
Filip Malý KIKM FIM UHK
37
Údržba souborů a adresářů unlink, link, symlink… Pomocí tohoto systémového volání lze odstranit soubor #include int unlink(const char *path); int link(const char *path1, const char *path2); int symlink(const char *path1, const char *path2); unlink odstraní adresářový záznam o souboru a sníží počet odkazů na něj v případě úspěchu vrací 0 jinak -1 Filip Malý KIKM FIM UHK
38
Údržba souborů a adresářů …unlink, link, symlink
Pokud je počet odkazů nulový, je záznam odstraněn z adresáře, i když je soubor otevřen nějakým procesem místo není obnoveno, dokud proces neskončí manipulaci se souborem a soubor neuzavře Toto systémové volání používá příkaz rm link vytvoří nový odkaz na soubor Obdoba ln symlink použijeme pro symbolické odkaz Jako ln -s Lze zavolat open a následně hned unlink je vytvořen soubor, který je ale ihned smazán – odstraněn z adresářové struktury – používá se pro pracovní soubory programu Filip Malý KIKM FIM UHK
39
Údržba souborů a adresářů mkdir, rmdir Pro tvorbu a odstranění adresáře #include <sys/stat.h> int mkdir (const char *path, mode_t mode); #include int rmdir(const char *path);
Filip Malý KIKM FIM UHK
40
Údržba souborů a adresářů chdir, getcwd Procházení adresářů jako v případě uživatelského cd, zjištění aktuálního adresáře pwd #include int chdir(const char *path); char *getcwd(char *buf, size_t size);
Funkce getcwd zapíše do proměnné buf název aktuálního adresáře Filip Malý KIKM FIM UHK
41
Procházení adresářů Procházení adresářů ve smyslu zjišťování souborů, které jsou umístěny v daných adresářích Hlavičkový soubor dirent.h Adresářový proud directory stream DIS * a funguje obdobně jako souborový stream FILE *
Filip Malý KIKM FIM UHK
42
Procházení adresářů opendir Otevře adresář a vytvoří adresářový proud, úspěchem je vrácení ukazatele na strukturu DIR Při selhání vrací nulový ukazatel #include <sys/types.h> #include DIR *opendir(const char *name); int closedir (DIR *dirp); struct dirent *readdir(DIR *dirp); long int telldir(DIR *dirp); void seekdir (DIR *dirp, long int loc); Filip Malý KIKM FIM UHK
43
Procházení adresářů readdir
Vrací ukazatel na strukturu popisující následující adresář v adresářovém proudu dirp Při chybě vrací NULL Zahrnuje
int_t d_ino i-uzel souboru char d_name[] název souboru
telldir
Vrací hodnotu udávající aktuální pozici v adresářovém proudu
Nastavuje ukazatel na adresářovou položku adresářového proudu dirp
seekdir
closedir
Zavře adresářový proud a uvolní s ním sdružené zdroje Úspěch vrací 0 Neúspěch vrací -1 Filip Malý KIKM FIM UHK
44
Příklad: jednoduchý výpis adresáře /*
We start with the appropriate headers and then a function, printdir, which prints out the current directory. It will recurse for subdirectories, using the depth parameter is used for indentation. */
#include #include #include #include #include
<stdio.h> <string.h> <sys/stat.h
void printdir(char *dir, int depth) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(dir)) == NULL) { fprintf(stderr,"cannot open directory: %s\n", dir); return; } Filip Malý KIKM FIM UHK
45
Příklad: jednoduchý výpis adresáře chdir(dir); while((entry = readdir(dp)) != NULL) { lstat(entry->d_name,&statbuf); if(S_ISDIR(statbuf.st_mode)) { /* Found a directory, but ignore . and .. */ if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0) continue; printf("%*s%s/\n",depth,"",entry->d_name); /* Recurse at a new indent level */ printdir(entry->d_name,depth+4); } else printf("%*s%s\n",depth,"",entry->d_name); } chdir(".."); closedir(dp); } /* end void printdir(char *dir, int depth) */ Filip Malý KIKM FIM UHK
46
Příklad: jednoduchý výpis adresáře /*
Hlavni funkce
*/
int main() { printf("Directory scan of /home:\n"); printdir("/home",0); printf("done.\n"); return 0; }
Filip Malý KIKM FIM UHK
47