Úvod do unixu, cvičení jaro 2014

Cvičení vede každé úterý 12:20 v SU2 Tomáš Gavenčiak (gavento@ucw.cz). Cvičení sleduje přednášku Libora Forsta.

Pro aktivní účast na cvičení je potřeba mít účet v počítačové laboratoři na Malé straně.

Zápočet

Účast na cvičení není povinná. Zápočet je za zisk 2/3 bodů za domácí úkoly. Do dvou týdnů po zadání jsou úkoly za plný počet, po dvou týdnech pak za polovinu. Zadané úlohy jsou zveřejněny níže na této stránce.

Odevzdávat řešení je možné jen do konce výuky v letním semestru!

Alternativní možnost je domluvit se se mnou na složitějším zápočtovém programu užívajícím shell, sed a awk. Program by měl řešit poměrně komplexní problém netriviálními technikami, součástí by měla být i krátká uživatelská dokumentace, podrobný help či manpage. Můžete přijít s vlastními návrhy, nebo zkusím něco vymyslet, ale program by měl být i kněčemu užitečný.

Na alternativním zápočtovém programu je třeba se domluvit do konce března. Termín pro odevzdání je pak konec výuky v letním semestru.

Jednotlivá cvičení a domácí úlohy

Domácí úlohy odevzdávejte elektronicky emailem jako holý text (u jednoduchých řešení stačí v těle emailu, složitější skripty raději přiložte jako soubory). Neposílejte mi scany ani fotografie papírů.

Je-li řešení netriviální a používá nějakou fintu či ošetřuje chtře nějaký případ, uveďte to – usnadní (či umožní) to čtení a pochopení řešení, zvlášť v případě, kdy v něm budete mít nějakou skrytou chybu.

Snažte se používat jen prostředky probrané na cvičení přibližně do zadání úlohy – jde o to procvičit vše a ne jen například trénovat sed :-)

Body za domácí úlohy najdete v této tabulce:

18. 2.Úvod do práce s shellem

Základní příkazy v shellu, jako man, ls, cd, pwd, cat, less(more), mkdir, rmdir, wc, metaznaky "'*|;\ a zmínka o dalších, escapování znaků, expanze *, ovládání shellu (šipky, Ctrl-C, Ctrl-D).

Povinná domácí úloha pro všechny

Přihlašte se z domu do nějakého počítače v labu pomocí ssh uživatel@stroj (z linuxu) nebo pomocí PuTTy (z windows), například na stroj u-pl21.ms.mff.cuni.cz.

25. 2.Procesy, přesměrování, pajpy a další příkazy

Příkazy a volby cp -r -p, rm -r -f -i, ls -d -l -a, ps -A -f, cat, wc -c -m -w -l, sort -n -R -r, head -n -c, tail -n -c, expanze * ? [0-9] [^abc]

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-2.tar.gz |tar xzvv

Úloha body (2b, plný počet do 11. 3.)

V souboru skore.txt v datech pro cvičení je seznam bodů (jedno číslo na řádku), které získali účastníci nejmenovaného turnaje. Pokud jich více získalo stejně bodů, sdílí spolu i místo. Kolik bodů získali ti, kteří jsou na 5-tém místě? Řešení by mělo být upravitelné i pro jiné místo než 5-té. Bude se vám hodit příkaz uniq či sort -u.

Úloha radky (2b, plný počet do 11. 3.)

V aktuálním adresáři vypište všechny soubory v pořadí podle počtu jejich řádek. Každý řádek výstupu by měl být ve formě pocet_radku jmeno_souboru. Chyby, které se objeví pro případné podadresáře ignorujte (nebo se jich chytře zbavte pomocí 2>/dev/null), exta položky pro adresáře zatím též řešit nemusíte, pokud nevíte jak.

Úloha poezie (1b-2b (a až 3b) podle kvality, plný počet do 11. 3.)

Vytvořte alespoň 4-řádkový soubor o luno zvici krajice chleba.txt s básní takovou, že se bude rýmovat a dávat (alespoň nějaký) smysl po každém provedení příkazu sort -R "o luno zvici krajice chleba.txt".

Úloha pevny-bod (2b, plný počet do 11. 3.)

Berme wc (bez parametrů či jména souboru) jako funkci z řetězců do řetězců (např. a b c\nde\n $\to$ 2 4 9\n). Najděte její pevný bod (tedy řetězec, který se zobrazí právě samy na sebe) a napište, jak jste to udělali. Rozhodněte též (a zdůvodněte), zda existují nějaké další pevné body.

4. 3.Práva, symlinky a hardlinky, přesměrování a další příkazy

Příkazy a volby diff, ln, cut, paste, split, tr, tee, id, chmod, chown.

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-3.tar.gz |tar xzvv

Úloha uzivatele (2b, plný počet do 18. 3.)

Vypište, kteří všichni uživatelé jsou zmíneni jménem v souboru /etc/group, každého jen jednou a na vlastní řádce.

Úloha slovni-spojeni (2b, plný počet do 18. 3.)

Náhodně zamíchejte (zpermutujte) dvojice přívlastek-slovo ze souboru fraze.txt z dat na cvičení.

11. 3.Regulární výrazy, příkazy find, sed, grep, dd

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-4.tar.gz |tar xzvv

Úloha histogram (3b, plný počet do 25. 3.)

Otestujte svůj náhodný generátor a v 1 MB náhodných dat spočtěte výskyty písmen a-z. Můžete použít například /dev/urandom, vyhněte se smyčkám, proměnným či odkládacím souborům, stačí jediná řádka příkazů a to, co už znáte.

Hint zdarma tomu, kdo si o něj řekne, ale bez něj jste o dost větší machři ;-)

Výstup by měl mít formu podobnou jako:

    42 a
  2345 b
     1 c
    18 d
    ...
  

18. 3.Aplikace sed-u a ed-u, příkazy curl, rename, iconv

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-5.tar.gz |tar xzvv

Úloha počasí (4b, plný počet do 1. 4.)

Napište příkazy, které ze serveru yr.no zjistí, jaké bude zítra počasí, a vypíše ho textově ve formě:

Predpoved na den 19. 3. 2014:
00:00-06:00 zatazeno 12 stupnu, vitr 6 m/s
06:00-12:00 zatazeno 8 stupnu, vitr 9 m/s
12:00-18:00 polojasno 11 stupnu, vitr 9 m/s
18:00-24:00 polojasno 12 stupnu, vitr 7 m/s
  
Body získáte i za řešení jen částečně odpovídající zadání, které ale bude dávat smysluplný výstup.

Úloha fotky (3b, plný počet do 1. 4.)

Soubory z adresáře foto v souboru s daty na cvičení přejmenujte (pomocí sed, find, mv, rename, ...) všechny do tvaru %d%d%d%d.jpg, kde číslo odpovídá číslu ve jménu souboru. Například tedy IMG_2040.JPG přejmenujte na 2040.jpg.

Update: Vzhledem k tomu, že existují dvě verze rename, "novější" zmiňovaná na cvičení (rename s/_[0-9]*\.jpg$/-000.džeypek/ foto/*) a "starší" (ale ve skutečnosti úplně jiný program), který jen nahrazuje podřetězce (rename .jpg .jpeg foto/*), tak není to novější rename všude k dispozici (například v labu).

Úlohu tedy vyřešte pomocí novějšího rename, nebo pomocí sed-u, mv či staršího rename. Cvičení je ale na regulární výrazy, vyhněte se tedy tomu, že byste každý typ pojmenování souborů přejmenovali zvlášť, zkuste naopak, aby řešení potenciálně zvládlo i jiné typy pojmenování.

P.S.: Už vidíte, k čemu se hodí držet se standardu :-)

25. 3.Shellové skripty, chybové kódy, proměnné, podmínky, expanze

Rychlý úvod do psaní skriptů v shellu: hlavička #!/bin/sh, co je příkaz a oddělovače, expanze proměnných ${PATH}, expanze příkazů $(echo 42), aritmetická expanze $[ 6*7 ], přiřazování do proměnných, parametry skriptu $1, $2, ... $#, $@, "$@", návratová hodnota (exitcode) příkazu, 0 = TRUE, $?, logické výrazy [[ 42 -gt 21 ]], [[ -e /etc/passwd ]] a různé operátory, spojování příkazů "logickými" && a ||, if cmd; then cmd; else cmd; fi.

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-6.tar.gz |tar xzvv

Úloha flipflop (3b, plný počet do 8. 4.)

Napište skript flipflop, který bude při opakovaném volání vracet střídavě flip a chybový kód 0, a flop a chybový kód 1. Stav si nějak ukládejte do souboru určeného prvním (a jediným) parametrem, pokud neexistuje, vytvořte ho. Pokud není zadán, použijte soubor .flipflop (začíná tečkou - "skrytý") v domovském adresáři uživatele.

Úloha suma (3+1b, plný počet do 8. 4.)

Napište skript suma, který sečte všechny své argumenty jako celá čísla a výsledek vypíše na standartní výstup. Pokud nedostane žádný parametr, nebo bude první parametr -h či --help, vypíše, jaké čeká parametry (help). Jeden bod navíc je za ošetření případu, kdy nějaký parametr nebude číslo, chybovou hláškou (například: Parametr "PI" neni cele cislo.).

1. 4.Pokračování shellu s kapkou sedu (zaskakuje Láďa Láska)

Zaskakuje Ladislav Láska, konkrétně: třídění 01, rev, tac, mazání slov délky nanejvýš 3, +=1, grep -o.

Úloha cut (4b, plný počet do 15. 4.)

Simulujte chování cut -f [sloupecky] -d ' ' s tím, že budete respektovat zadané pořadí sloupců, tedy například echo A B C D | cut-f.sh 4,1,2 vypíše D A B. Sloupce budou zadány jen jako čísla oddělená čárkou, nikoliv rozsahy, sloupců bude nanejvýš 9. Vstup bude mít vždy dost sloupců, cokoliv za posledním sloupcem zahrňte do posledního sloupce.

Hint: Vzpomeňte na náplň cvičení. Nebojte se vygenerovat si jeden příkaz jiným příkazem.

8. 4.Další konstrukce v shellu (zaskakuje Honza Musílek)

Zaskakuje Honza Musílek, složitější konstrukce v shellu (expanze ${PROMENNA:-DEAFULT}, funkce, ...) a další příklady.

Nebyly zadány domácí úkoly.

15. 4.Procesy a signály

Textové zadání cvičení a řešení vyrobené na cvičení: trapper.sh, killer.sh, trapper-daemon.sh (nově s funkcí listen).

Úloha spammer (5b, plný počet do 29. 4.)

Napište skript pro hromadné rozesílání e-mailů. Jako svůj první parametr bude očekávat slovo add, remove, list nebo send, jako druhý parametr (u add a remove) e-mailovou adresu, případně (u send) předmět e-mailu.

V případě zadání chybné adresy, případně adresy která už v seznamu je (u add) nebo není (u remove) vypíše chybovou hlášku a skončí. Počítejte s tím, že v textu e-mailu se může objevovat prakticky cokoliv (kromě null bajtu).

22. 4.Atomické operace, zámky a úloha paralelní zpracování úkolů

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-10.tar.gz |tar xzvv

Společné řešení složitějšího příkladu podle zadání v souboru. Příprava na více procesů paralelně přistupujících ke společným adresářům. Atomicita mv a varování před neatomicitou cp a spol. a též zápisem do společného souboru. Zámky pomocí flock.

K dispozici je trochu učesaný a nehotový, ale funkční skript pro workera: worker.sh.

Poznámka ke cvičení: Problémy s [ -z $F ] pramení z toho, že pokud je F prázdný string (což ls prázdného adresáře je), tak je ve skutečnosti spuštěn příkaz [ -z ], a zjišťuje se tedy neprázdnost řetězce "]", který neprázdný je. To, že pak chybí uzavírací "]", některým implementacím bashe vůbec nevadí. Takové chování je ale ve skutečnosti to, co byste čekali — například při volání find adresar/ $PODMINKY v případě, že jsou PODMINKY prázdné, nedostane find jako druhý parametr prázdný string, ale dostane jen první argument; v případě, že PODMINKY="-type f -name *.txt", dostane find parametrů celkem pět.

Správné řešení je tedy [ -z "$F" ], které při prázdném F opravdu vytvoří prázdný string jako parametr pro [.

Úloha worker (2+2b, plný počet do 6. 5.)

Pro následující úkoly upravte worker.sh výše. Snažte se o co nejméně změn (například ve struktuře) a aby bylo vidět, co jste jak změnili (například diff-em) — nejlépe změny krátce popište. Též se snažte, aby byl výsledný kód tak nějak elegantní. Výsledek prosím otestujte :-)

a) Upravte worker.sh tak, aby logoval události i do souboru jobu, jak je uvedeno v zadání. Můžete použít stejný formát, jako už je použit u workera.

b) Upravte worker.sh tak, aby prioritizoval joby ve frontách podle data vložení, například tak, jak je naznačeno v zadání. Worker nemusí brát nejdříve vložený soubor přes všechny fronty, stačí, když z libovolné fronty vezme její nejdříve vložený soubor. Inbox by měl mít stále přednost.

29. 4.Parameter expansion, dokončení workera, manager a wait

Probrali jsme různé expanze parametrů, od $VAR a ${VAR} přes ${VAR:-default}, ${#VAR}, ${VAR/co/zaco/}, ${VAR#odrezat-zacatek}, ${VAR%odrezat-konec}, ${VAR:offset:delka} až po ${!prefix@}. S pomocí těchto, seq a eval detekce palindromu a výpis hodnot proměnných začínajících na "H".

Dokončili jsme počítadla pro worker.sh, napsali jednoduchý manager.sh a sledovali, jak se workeři (korektně) perou o úlohy.

Příkaz pro zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-11.tar.gz |tar xzvv

Skripty worker.sh a manager.sh.

6. 5.AWK

Zopakování syntaxe a sémantiky awk, psaní skriptů pomocí #!/usr/bin/awk -f, proměnné v awk, různé separátory záznamů (RS) a polí (FS). Odkaz na poznámky ke cvičení Honzy Musílka: [1] [2].

Napište sčítačku, která sečte všechna čísla na vstupu (i nula nebo více čísel na řádek).

  # oddělovač záznamů je regulární výraz
  BEGIN { RS="[\n\t ]" }
  { sum += $0 }
  END { print sum }
  # jiné řešení s for
  { for (i=1; i<=NF; i++) sum += $i }
  END { print sum }

Napište "wc -l" a "wc -c".

  # wc -l
  END { print NR }
  #wc -c
  BEGIN { FS="" }
  { sum += NF }
  END { print sum }

Napište program, který sloučí více po sobě jdoucích prázdných řádků do jednoho.

  # záznamy jsou "odstavce" oddělené jedním a více prázdným řádkem
  # výstupní oddělovač bude prázdný, odstavce oddělíme ručně
  BEGIN {RS="\n{2,}"; ORS=""}
  NR > 1 {print "\n\n"}
  { print $0 }

Chování ARGC a ARGV: V těchto proměnných jsou na začátku další parametry předané awk nebo skriptu. Po BEGIN z nich awk bere jména souborů ke zpracování, a na další jméno souboru se podívá až po zpracování předchozího; můžete je tedy volně měnit, například v BEGIN nastavit ARGC=1 nebo někdy před či v ENDFILE (konec zpracovávání každého souboru) toto pole rozšířit.

Úloha soucet (5, plný počet do 20. 5.)

Je konec. Vaše body budou sečteny a zváženy. Vaším vlastním awk skriptem.

Body jsou v CSV tabulce, kde jsou položky na řádcích odděleny středníky. První řádek je hlavička se jmény úloh, další řádky výsledky jednotlivých řešitelů: první sloupec obsahuje jméno řešitele, další vždy body za danou úlohu. Například:

Jmeno;Jednoducha uloha;Tezsi uloha;Nejasne zadana uloha;Trivka;Nedatelna
Adam;2;1;;2;3
Beatrice;;;;;5
Cyril;1;1;1;1;1
Daemon;2;3;4;;
Eugene;1;0;1;1;4

Maximální počet bodů za úlohu je získané maximum za tuto úlohu; v tabulce není nikde zapsané a musíte ho spočítat. Vytvořte textovou tabulku s celkovými výsledky ve formě:

Jmeno       Suma   Uspesnost   Zapocet
Adam           8         50%        Ne
Beatrice       5         31%        Ne
...
Odevzdano 18 z 25 reseni.

Zápočet je za 66% bodů. Je důležité dodržet zarovnání na sloupce, ale přesný počet mezer je na vás. Řešení je odevzdané i pokud je za 0 bodů.

Úkol vyřešte v awk – nejlépe jako skript, který se spustí jako ./soucet.awk body.csv, ale pokud potřebujete, můžete si i vypomoct kouskem shell skriptu pro obalení.

Tato úloha je poslední zadaná.

13. 5.Cvičná implementace make

Příkaz pro rozbalení dat a zadání ke cvičení:
curl gavento.ucw.cz/vyuka/2014-unix/cv-12.tar.gz |tar xzvv

Cvičení s příkladem zkouškového typu – implementujeme zjednodušený make podle zadání.

20. 5.Dokončení implementace make

Společná implementace make podle zadání z minula. Na cvičení se stihla velká většina, finální kód včetně detekce cyklů: make.sh. Ozkoušet ho můžete na datech z minulého cvičení. Pozor, na to, že skript zpracovává Makefile z aktuálního adresáře, proto je třeba něco jako například bash ../../make.sh clean main.o.

Tento příklad je na zkouškový poměrně obtížný, na zkoušce buď očekávejte spíš něco objemu jedné jeho poloviny. Práce s textem je v shellu dost protivná, jak je vidět zde, spousta příkladů proto pracuje se soubory, adresáři, jednotlivými řádky souboru a pod.

Hodně úspěchů u zkoušky!

Materiály

Zdroje na stránce přednášky

Kniha Shell v příkladech — spousta praktických řešených i neřešených příkladů (online)

Otevřený standart POSIX.1-2008 — verze s dodatky do 2013

Stránka cvičení Honzy Musílka — konkrétní řešené úlohy a další zdroje

Stránka cvičení Ládi Lásky — konkrétní řešené úlohy

Jaj