Deprecated: Function set_magic_quotes_runtime() is deprecated in /DISK2/WWW/lokiware.info/mff/wakka.php on line 35
Úvod Do Unixu – zkoušky 2007
Vyriesene minulorocne pisomky
Tym co maju skusku este len pred sebou sa urcite hodi subor s vyriesenym velkym mnozstvom minulorocnych pisomiek –
file:pisomky.pdf
nardew
18.5.2007 – 1. Předtermín
Muhehe, tak první zkoušku mám úspěšně za sebou, jen tak dál...
Probíhalo to asi takhle: Forst nám dal na výběr z pěti čísel (zadání), přičemž po našem výběru demokratickým hlasováním prohlásil, že je to těžký zadání. Nešlo ale ani tolik o to, napsat celý příklad (Forst sám ani nevěděl, jestli se to dá stihnout za dvě hodiny naprogramovat), jako o to, mít toho co nejvíc a pokud možno správně. Je otázka, jestli to takhle bude i na dalších termínech, ale skoro bych si tipnul, že jo. Já jsem třeba stihnul rozmyslet si, jak na to půjdu, udělat parsování optionů a naimplementovat funkci checkout, přičemž jsem tam měl poměrně dost škrtanců a vsuvek. I tak jsem ale měl jednu z písemek, který se mu «ne až tak líbily», což znamenalo pěknou dvojku. Takže bych doporučoval si hlavně procvičit takový ty REGEXPy, SEDy, GREPy apod., abyste tam neměli zbytečný chyby. Co se týče výsledků, tak byly vesměs jedničky, dvě dvojky a dva lidi vylítli. Jo a nějakou záhadou se nám povedlo vyhnout se ústnímu dozkušování, což se ale možná dá vysvětlit tím předtermínem, možná taky víkendem, takže na to bych se u dalších termínů moc nespoléhal.
A teď už k
Zadání:
Naprogramujte vlastní jednoduché CVS
Tj. program, který bude schopen uchovávat na vzdáleném serveru nějakou adresářovou strukturu se všemi verzemi a revizemi. Bude možné si stáhnout nejnovější verzi celého adresářového stromu nebo jenom jeden file, případně si explicitně říct číslo starší verze souboru, kterou chceme stáhnout. Dále bude skript podporovat upload na server, přičemž by měl kontrolovat, jestli se číslo verze souboru, který chceme updatovat, od posledního stažení nezměnilo (tj. jestli ten soubor nenahradil novější verzí třeba někdo jiný). Pro umožnění přístupu více lidí by program měl nějak používat zámky. Pro jednoduchost je přípustné zamknout celé CVS a pustit k němu další uživatele až po skončení relace současného uživatele.
Pozor! Není dovoleno si na serveru ukládat přímo všechny verze všech souborů. Musíte tam mít třeba jenom tu nejnovější a potom k ostatním verzím si tam schovávat nějaké diffy od téhle nejnovější verze, nebo tak podobně.
Ke kopírování z/na vzdálený server jsme byli poukázáni na příkaz
scp [user@host:]sourcefile [user2@host2:]destfile. Ke komunikaci se serverem a posílání příkazů na něj se dalo dobře použít
SSHčko. Jo taky se někdo ptal, jestli může používat v tom skriptu RCS (což je, jak jsem to já pochopil už nějaký existující GNUácký CVSko), tak to samozřejmě možné není :-)
Dále můžeme pro jednoduchost předpokládat, že všechny soubory budou textové.
Skript má tedy umožňovat tyto příkazy:
mycvs checkout {remotepath} {user} {machine} – Stáhne nejnovější verzi celého adresáře v
remotepath na serveru
machine.
User slouží k připojení k
SSHčku. Navíc si potom někde musíte uložit tu
remotepath, toho
usera a
machine, protože ty další příkazy to už mají podle těchhle informací detekovat samy – tyhle parametry se jim už předávat nebudou.
mycvs update [-r revision] [files] – Stáhne ze serveru revizi
revision souboru/ů files, případně celého stromu, když
files chybí a nejnovější revizi, když chybí
revision.
mycvs commit [files] – Uploadne na server lokální verze souborů
files, případně celého adresáře a nastaví je jako nejnovější revizi. Pokud ale zjistí, že se mezi naším updatem a commitem nějaký soubor na serveru změnil, tak o tom musí uživatele nějak informovat a třeba se ho zeptat, jak dál.
Příkazy commit a update by měly umět detekovat místo v adresářové struktuře, kde se nachází a podle toho se zachovat (ne hledat informace o CVSku, které vygeneroval checkout, v současném adresáři apod.)
A takovej bonbónek nakonec – V souborech se může vyskytovat řetězec
$ID:...něco...$ Úkol je to
...něco... při stahování na lokální počítač nahradit jménem souboru, číslem verze a datem, takže to pak bude vypadat nějak takhle:
$ID: soubor.txt 2.5 18 kvě 2007$
Tak doufám, že jsem vás moc nevystrašil. Hlavně, jak už jsem říkal, berte v potaz, že to byl předtermín a že neni potřeba udělat všechno. Forst sám prohlásil, že třeba na posledním termínu v září by takovejhle příklad nedal.
P.S.: Možná jsem prohodil příkazy update a commit, nebo se jmenovaly nějak jinak. Každopádně mají dělat to, co jsem popsal. CVSko neznám, takže to klidně někdo opravte, když se vám to nebude zdát.
Čestmír21.5.2007 – 2. předtermín
Zadání
oldtimer
Napsat skript, který dostane jako
parametry seznam souborů a adresářů a s nimi provede:
1)
soubory (.c, .h v ANSI normě)
převede do K&R C
*
komentáře // nahradí za /* */, pozor, K&R C nezná vnořené komentáře -> musí se ošetřit
*
deklarace funkcí návratový_typ identifikátor(typ1 ident1, typ2 ident2, ...);
přepsat na návratový_typ identifikátor(typ1, typ2, ...);
(tři tečky znamenají, že tam může být víc identifikátorů, ne va_list)
*
definice funkcí návratový_typ identifikátor(typ1 ident2, typ2 ident2, ...){
přepsat na návratový_typ identifikátor(ident1, ident2, ...)
typ1 ident2;
typ2 ident2,
...
{
v definicích a deklaracích můžou být odřádkování, je třeba ošetřit
naopak nemusí se počítat s funkcionálními parametry(rozuměj: nebudou tam vnořený kulatý závorky)
2)
v adresářích (a všech podadresářích) vezme
všechny .c soubory a s nimi provede bod 1
3) pokud někde v průběhu narazí na
#include neco, tak s tim necim opet provede bod 1(a 3), pokud k nemu ma
pravo zapisu. Bacha na zacyklení -> ošetřit
Průběh
Po zadání a dotazech (cca hodina) jsme měli 2 hodiny na psaní.
Odpoledne po přednášce a vcelku stresujícím čekáním na výsledky (všichni sebou trhli, jakmile se ozval jakýkoliv zvuk(např. cinknutí výtahu, cvaknutí dveří apod.))
nám Forst řekl krátce, jak si představoval řešení, oznámil výsledky(nějaký jedničky, jedna dvojka, něco nedostatečných) a zbytek si dozkoušel ústně, u toho už jsem nebyl, tak nevím, jak to probíhalo.
tk
Ustne spis prochazel to co jsme vytvorili, ukazoval chyby, rikal jak by se to dalo delat, obcas asi ukazal nejakou chybu a chtel po nas abychom si ji opravili.
Pokud vim tak od ustniho byly neco jako same dvojky a jedna trojka nebo tak. Jak dopadl clovek ktereho chtel vyhodit a on si taky jeste chtel povidat, to nevim.
K.B.
24.5.2007
Včerejší zkouška probíhala zajímavě, Forst přišel a prohlásil, že se vyspal na toto zadání:
Zadání:
Naprogramujte test (bez používání příkazu test či "[") :). Test musí mít několik svých běžných vlastností :
e|f|b|c|s file oznámí, zda soubor existuje|je regulérní soubor|je adresář|je speciální zářízení block device|je spec. zař. kdovíco :)|existuje s nenulovou délkou
L file oznámí, zda je to link
r|w|x file oznámí práva k souboru (pro aktuálního uživatele !! !! )
file1 nt|ot file2 porovná, který soubor, že první soubor je mladší|starší
file1 ef file2 porovná, jestli oba soubory jsou stejného inodu (pozor, na různých discích může dojít ke shodě inodu)
n|z str1 zjistí, zda je řetězec neprázdný|prázdný (nebo naopak, teď nevim)
str1 <|> str2 zjistí, zda jsou řetězce lexikograficky uspořádány.
Tohle by ještě byla legrace, ale pak to přišlo...
Test musí být volán jako test, nebo "[", s příslušnou kontrolou. Je nutné, aby také uměl vyhodnocovat závorky (a to I VNOŘENÉ!! !! ) společně s logickými podmínkami u přepínačů -ao a !". Test vrací obvyklou návratovou hodnotu. Na práci byly 2 hodiny.
Řešení:
Hodně věcí se dá dělat pomocí expr, který toho mraky umí (viz man expr). Některé části jdou pomocí ls, find, diff. Závorky se nějak dají parsovat a předat shellu jako logický výraz s nulami a jedničkami (což jsem nějak nepobral – jestli to čte někdo z těch, co tam byli se mnou, ať mě opraví :) ). Celkem mi přišel příklad jako docela obtížný, člověk opravdu musí znát každý slajd, aby to byl nějak schopen dát dohromady.
Výsledky:
Úspěšní řešící měli většinou domyšlené skoro všechny přepínače, nejlepší z nich měl dokonce téměř vyřešenou i tu hroznou rekurzi. Forst naše testy prohlásil za peklo. Celkem to rozdal takhle:
1x jednička
4x (nebo něco takového) dvojky
4x povídání
zbytek (na zkoušku přišlo 16 lidí) pápá...
28. 5. 2007
Po zajimavem hlasovani o zadani (dost naslepo..) se Forst moc zaradoval, ze to uz tady mooooc dlouho nebylo
Zadani:
Napiste v shellu sort, ktery nepouziva sort. Pozadovane vlastnosti: je stabilní (zbytecne nezprehazi polozky se stejnym klicem), umi radit podle vic sloupcu, umi ruzne oddelovace poli, ma prepinac na numericke razeni, prepinac na ignorovani zbytecneho whitespace, prepinac na ignorovani case (velka/mala pismena) a prepinac na reverzni sort. Muzeme pouzivat gnu extensiony.
Přesné zadání:
mysort [options]
..kde [options] mohou být libovolněkrát a v libovolném pořadí:
-kFROM[,TO][rnfb]
-tDELIMITER
DELIMITER je oddělovač polí (jeden znak), FROM a případně TO udávají rozsah polí, podle kterých se má řadit. U každého řazení mohou být různé přepínače, přičemž 'r' je reverse, 'n' donutí sort řadit numericky (11 > 2), 'f' ignoruje case a 'b' ignoruje mezery.
Takže suma sumárum to může vypadat třeba takhle:
mysort -t: -k2n -k3,5rbf
..což řadí nejprve podle druhého sloupce numericky a pokud tam je shoda, tak podle 3.-5. sloupce reverzně s ignorováním mezer a case.
Podminka – soubor se nevejde do pameti => Není kupříkladu možné si obsah nasypat do awk, pořešit a vrátit.
Reseni:
Obecně existovaly dvě možnosti jak se postavit k tomu, že je možné řadit podle několika klíčů. Zaprvé, všechny klíče si zapamatovat a při porovnávání dvou řádek je postupně porovnávat podle každého klíče, dokud nemáme rozhodnuto, která řádka je větší/menší. Zadruhé, seřadit vstup podle posledního klíče, pak podle předposledního klíče a tak dále až nakonec podle prvního klíče, přičemž je potřeba mít zaručené, že řadíme stabilně, což bylo nicméně stejně součástí zadání.
Co se metody tyce, nebylo spatne to rozkouskovat na hromadu souboru a pak pouzit nejakou shellovou alternativu mergesortu. Musite ale davat bacha na to ze shellove funkce nemaji lokalni promenne, takže je potřeba volat rekurzivně subshell a ne funkci. Setrideni v n^2 nevadilo nicemu (za bubblesort bylo za 1).
Já jsem si třeba vytvořil soubor s čísly 1 až počet řazených řádků, v něm jsem přehazoval čísla a na konci podle jejich pořadí přeskládal řádky vstupu a taky za jedna. Zkrátka možností je mnoho.
Vysledky:
asi
5 jednicek
2 dvojky
4x povidani
4x ne-e-e
Poznamka:
Libor Forst pri predavani reseni zcela necekane nasel na stole papirovou maketu psa, zaradoval se a rekl, ze ho musi ukazat babicce.
04.06.2007 – SHOWMAN
http://forum.matfyz.info/viewtopic.php?t=3273
05.06.2007 – Databáze pracovníků UK
Tak dneska to bylo celkem jednoduché. Měli jsme udělat whoman:
-databáze pracovníků a pracovišť
Parametry
-addperson ID JMENO PRACOVISTE # přidá osobu do db
-addperson ID PRACOVISTE # prida osobu do dalsiho pracoviste
-change ID (zkratka toho co chceme zmenit) VALUE
-changehead PRACOVISTE ID # změní vedoucího pracoviště
-print /pat/ nebo WD # hledá v jmenéch pracovišt a osob – pro pracovište vytisknout pracovniky a podřízené pracoviště a pro osoby + kde je vedoucím
to je asi tak vše. Bylo nás 7. Z toho 3 jedničky a zbytek si šel povídat (ale asi to dali všichni nebo skoro všichni) –
Jiří Kunčar
7. 6. 2007 – getopt
Myslím, že se nám poštěstilo dostat jedno z příjemnějších zadání: Obdoba utility, resp. knihovní funkce pro C,
getopt zadaná takto:
Pro neznalé: Krátké přepínače sestávají z jednoho znaku a mohou se vyskytovat samostatně (
-a – b -c) nebo po skupinách (
-abc, nebo i
-abcParametrProC). Případné parametry jsou ke krátkým přepínačům přilepené nebo po nich následují (tzn. jsou v následujícím argumentu). Dlouhé přepínače mají prefix
-- a případný argument je k nim přilepen pomocí znaku
=. Parametry mohou obsahovat libovolné(!) znaky, přepínače mohou obsahovat
[A-Za-z0–9_] a dlouhé podle mě i
-.
Jinak parametry bez přepínačů se nijak nevyhodnocují, jen se vypisují v
usage.
Na zkoušce nás bylo dost, od každé známky pár lidí a nějací to také neudělali. Nejvíc si asi Forst vystřelil ze mě. Jmenoval mě spolu s dvěma dalšími (nevím, jak dopadli, jeden z nich dělal zkoušku už podruhé a zjevně se mu to moc nepovedlo ani teď) až po trojkařích, že mě chce dozkoušet ústně. Když na mě přišla řada, řekl mi, že tam používám «bashové věci», tak mi došlo, že jde o ořezávání řetězců pomocí %%/##, přepsal jsem to do sedu a pak mi dal jedničku. (BTW, není to žádná bashovina, je to v SUS i POSIX a je to z korn shellu, dneska to má každý rozumný shell, to jsem mu taky řekl ;) —
Adam
Forstovi hlavně vadilo, když lidi nedali ve skriptu najevo, že chápou, co znamená
"$@" (narozdíl od
"$*"), když nepředpokládali mezery v parametrech nebo neuměli správně použít pojmenované proměnné (pokud je použili k uložení obsahu konfiguráku).
Riešenie je asi zbytočné písať, ak ste to celé napísali napr pomocou jedného
veľkého if-u, prípadne
case-u (a potom sa nedostavili na vyhodnotenie ;), tiež ste to mohli bez problémov dostať za 1. A mať potom čo oslavovať :D —
Pepe
14. 6. 2007 – showlog
Filtrování záznamů se syslogu.
Máme soubory /var/log/messages a starší již odrotované /var/log/messages.[
0–9]+.(gz|bz2). Váš skript bude zobrazovat záznamy z určitého časového intervalu, s určitým PID a určitou minimální důležitostí. Jedna řádka syslogu je ve tvaru:
krátký název měsíce, den (s mezerou na začátku místo nuly), název programu, PID, prefix: 4 písmena-3 čísla-důležitost, text zprávy
Feb 6 14:54:03 apache[1234]: ABCD-123-E Error 404: page not found
Důležitost (severity) je zadána v programu jako proměnná. XACEWID (emergency, alert, critical error, error, warning, info, debug).
Program bere parametry:
- -d [±]datum – datum od (-), do (+), formát podle libosti, př.: -d -20 -d +45 = od 20. dne v roce do 45. dne v roce.
- může být lib. kombinace = nic, +, -, ±
- roky se pro zjednodušení vůbec neuvažují
- -t [±]čas – čas od (-), do (+) – týká se odpovídajícího data z parametru -d, formát podle libosti, př.: -t -12:00:00 -t +18:00:00
- -p [0–9]+ – číslo PID – vypsat pouze záznamy s tímto Process ID
- -l [XACEWID] – (jedno z těchto písmen) – vypsat pouze záznamy s touto a vyšší důležitostí
-
Vypisují se pouze odpovídající řádky v nezměněné podobě.
Soubory /var/log/messages* mohou být obrovské (řádově MB, ale klidně i TB :), takže je blbost je celé rozbalovat (=> zastřelit!) :)
Nástin řešení:
- parsování parametrů – while, case, shift, expr (substr, match)
- BTW, jak se do Forstových slajdů dostala GNU rozšíření substr, match apod. příkazu expr, která nejsou v normách ani na žádném BSD, když tvrdí, že používá jen FreeBSD, a bazíruje dokonce i na tom, abychom používali Bourne shell bez rozšíření? (Jen taková řečnická otázka...;)) — Adam
- data a časy to chce pro porovnávání převádět na číslo
- datum – převést třeba na den v roce – buď přes příkaz date (viz %j, %a, %d, -j, -f), nebo přes asociativní tabulku
- čas – odstranit dvojtečky :), nebo složitěji počet sekund ve dni
- pak je potřeba najít začáteční a koncový soubor a hledat v nich
- na to lze jít pod souborech od nejmladšího, očuchávat měsíc na prvním řádku a hledat, kde se mění nerovnost
- hodí se příkazy cat, zcat a bzcat + head -n 1 (pajpu to zalomí za prvním bufferem, takže se to nebude rozbalovat celé)
- je dobré si napsat funkce na filtrování podle PID a důležitosti
- důležitost – stačí oříznout za daným levelem a pak to hodit do hranatic
- ...a pak i s pidem udělat jeden pattern pro grep
- a také funkci na filtrování podle časového intervalu
- pak vezmeme nalezený interval souborů, kde to vše je, a proženeme jej filtry
- pozor: za brute force prohledávání všech souborů může být «Forst brutální» a vlasy mu tvoří ortogonální bázi
- takže unixové rčení Premature optimization is root of all evil! brát tady s rezervou...
- jo a rekurzi si raději pověste doma na hřebík a šetřete si ji na zimní večery s lispem
- takže to chce starý poctivý while, nějaké casy a pár ifů a hlavně ne stránky zbytečných knihoven funkcí, které lze provést elegantně na jeden řádek
Jedno řešení může být docela blízko jedničce i čtyřce... :) Ne fakt, i když byl Forst dost znechucen všeobecnou úrovní skriptů, nakonec mi dal za 3, protože mimo ten úlet s catem na vše jsem to měl celkem slušné a měl jsem tam (sice zaškrtané) rozpracované to hledání. :) Takže hodně zdaru!
--
Bohouš
opravička: ještě ti tam chybí úroveň N v severity, tuším že byla mezi W a I, tedy [XACEWNID]
Já to řešil tak, že jsem si udělal fci, která dostane jeden parametr a to vstup souboru a na obrazovku vysype z tohoto souboru všechny řádky, který splňují daná kritéria (to není nic světoborného :-) ). Pak jsem si načetl optiony a naplnil si tak nějaké globální proměnné, které figurovaly v již zmíněné fci pro výpis (to taky není nic zvláštního). No ale ten samotný výpis správných souborů jsem dělal tak, že jsem si nejdřív načetl do pomocného souboru všechny soubory (tj. messages i vsechny messages.n.gz) a pak jsem v cyklu procházel tento seznámek, každý soubor jsem si rozbalil do souboru messages.n, přečetl pouze první a poslední řádek, abych zjistil, jestli jsem ještě v časovém intervalu, a když jsem byl, tak jsem ten rozbalený soubor poslal na výpis do fce, a když jsem přešvihl datumový interval, tak jsem zabalil celý cyklus, protože pochopitelně dál už to nemělo smysl kontrolovat, tam by už nic na výpis nebylo ;-) (svůj rozbalený soubor jsem pochopitelně zase smazal – takže se mi tam nehromadily TB dat, za což Forst kotel řádil)
Těm co tam ještě nebyli, tak hodně zdaru a hodně štěstí na zadání. Tohle si myslím bylo zřejmě z těch lehčích. Jo a taky říkal, že teď bude hodně zkoušet nové zadání, takže pro ty co ještě nebyli, moc nespoléhejte na starší zadání. Ale určitě doporučuju si to projít, protože tam jsou mega dobré a hlavně inspirativní postupy.
MateSC