Příklady na procvičení shellu
=============================
(řešení je v reseni_shell.txt)
-------------------------------------------------------------------------------
A) základní příkazy pro manipulaci se soubory
-------------------------------------------------------------------------------
1. Kolik v systému existuje uživatelských účtů?
2. Vypište řádky č. 10 až 20 souboru /etc/passwd.
3. Kolik souborů (všech, včetně jmen začínajících tečkou) je aktuálním
adresáři?
4. Uložte manuálovou stránku k shellu bash do souboru bash.man a pak
spočítejte, kolik je v souboru slov.
5. Vytvořte soubor xxx, který má čas poslední modifikace stejný jako soubor
/etc/services.
6. Napište příkaz, který bude vstup z klávesnice ukládat do souborů s1 a s2.
7. Uložte do souboru xxx první a poslední řádek souboru /etc/group.
8. Napište příkaz, který bude vypisovat obsah adresáře /bin po stránkách na
obrazovku (pomocí more nebo less) a zároveň ukládat do souboru ls-bin.
9. Vytvořte adresář dir a v něm soubor takový, že nepůjde zjistit jméno tohoto
souboru pomocí ls, ale kdokoliv, kdo zná jméno souboru, do něho může
zapisovat, ale ne číst. Výjimkou je vlastník souboru, který ho může číst, ale
ne zapisovat. Ověřte funkčnost ve spolupráci s jiným uživatelem. Jakými
různými způsoby lze nastavit požadovaná práva?
-------------------------------------------------------------------------------
B) komunikace mezi uživateli, identifikace uživatelů
-------------------------------------------------------------------------------
1. Pošlete svému kolegovi na obrazovku výpis obsahu (s podrobnými informacemi
o souborech) adresáře o jednu úroveň výše, než je aktuální adresář.
2. Pošlete svému kolegovi na obrazovku obsah souboru /etc/profile.
3. Pošlete svému kolegovi e-mailem (subject bude "Soubor") obsah souboru
/etc/inetd.conf.
4. Jak způsobíte, aby se vám veškerá došlá pošta ukládala nejen do
standardního mailboxu, ale i do souboru ~/inbox? Připravte soubor ~/.inbox
tak, aby byl přístupný pouze vám.
5. Zjistěte, do kolika skupin uživatelů patříte.
6. Nastavte forward pošty tak, aby se do souboru ~/prehled_posty pro kazdy
dosly mail zapisovalo datum jeho prichodu.
-------------------------------------------------------------------------------
C) diff, comm, cut, paste, split, sort, tr
-------------------------------------------------------------------------------
1. Vypište čísla skupin, která jsou použita v /etc/passwd. Každé číslo by mělo
být vypsáno právě jednou.
2. Vypište obsah /etc/passwd setříděný (numericky) podle UID.
3. Vypište obsah /etc/group setříděný podle jména skupiny.
4. Vypište plná jména uživatelů setříděná sestupně podle login name.
5. Vypište loginy uživatelů ve dvou sloupcích, v levém v původním tvaru,
v pravém se všemi malými písmeny převedenými na velká. Sloupce jsou odděleny
znakem '='.
6. Vypište loginy uživatelů oddělené mezerami po pěti na řádku, setříděné
zleva doprava.
7. Vypište jména skupin do 10-ti řádků, na každém řádku jsou skupiny oddělené
čárkami.
8. Změňte v souboru /etc/passwd každý výskyt znaků 'w' a 'W' na '@' a pomocí
diff zjistěte, které řádky byly změněny.
9. Vypište čísla skupin, která existují v /etc/group, ale nejsou použita v
/etc/passwd.
-------------------------------------------------------------------------------
D) find
-------------------------------------------------------------------------------
1. Napište, příkaz, který vypíše počet všech pro vás viditelných adresářů
počínaje rootem ('/').
2. Napište, příkaz, který smaže všechny soubory 'core' staré aspoň 5 dní.
3. Napište, příkaz, který vypíše seznam všech rootem vlastněných programů,
které jsou spustitelné pro uživatele, skupinu i ostatní uživatele.
4. Napište, příkaz, který smaže všechny objektové soubory (*.o) nezměněné
aspoň 2 dny v podstromu vašeho domovského adresáře.
5. Napište, příkaz, který vypíše počet všech záložních kopií souborů
editovaných editorem vim (*~) vlastněných uživateli 'root' a 'nobody'.
6. Napište, příkaz, který u všech obyčejných souborů v podstromu vašeho
domovského adresáře, které mají nastavené právo spuštění, vypíše informace o
jejich typu (zda jde o binární spustitelné programy, shellové skripty, apod.)
7. Napište, příkaz, který pro každý soubor 'core' v podstromu vašeho
domovského adresáře vypíše jeho velikost v bytech.
8. Napište, příkaz, který vypíše počet všech speciálních souborů zařízení
(znakových i blokových) v celém stromu souborů.
9. Napište, příkaz, který vypíše jména všech zdrojových souborů v C (končí
příponou .h nebo .c) vlastněných vámi nebo uživatelem root v celém stromu
adresářů.
-------------------------------------------------------------------------------
E) vi
-------------------------------------------------------------------------------
1. Vyzkoušejte si základní editační akce (spuštění editoru, pohyb kurzoru,
vkládání, mazání, přepisování znaků, uložení souboru, ukončení editoru).
2. Vyzkoušejte si práci s bloky (přesun, kopírování a mazání bloků textu) a
značkami (označení místa v textu).
3. Vyzkoušejte si práci s více soubory, v editoru vim i s více okny.
4. Vyzkoušejte si vyhledávání a nahrazování v textu.
5. Vyzkoušejte si další možnosti editoru (konfigurační proměnné, makra, další
editační příkazy). Je dobré si pustit gvim nebo vim a pak si projít help.
6. Zrušte v /etc/services všechny řádky, a obsahují řetězec 'udp'.
7. V /etc/services zakomentujte (vložením '#' na začátek) řádky obsahující
řetězec '/tcp'.
8. V /etc/services ponechte pouze komentáře (řádky začínající '#').
9. Změňte řádek v HTML souboru
Obrazek: ...
na
Obrazek: ...
Řešení by mělo fungovat pro libovolnou pozici kurzoru na řádku a bez použití
šipek (a jejich ekvivalentů h, l, space, backspace).
10. Změňte řádek
toto je orbaceen
na
Toto je obracene
Řešení by mělo fungovat pro libovolnou pozici kurzoru na řádku a bez použití
šipek (a jejich ekvivalentů h, l, space, backspace).
11. Změňte
radek
2
radek 1
na
radek 1
radek 2
Předpokládejte, že kurzor je na 'radek 1'.
12. Změňte řádek ve zdrojovém textu programu v jazyce C
if((outf=open(argv[2],O_EXCL|O_TRUNC,0666))==-1) {
na
if((outf=open(argv[2],O_WRONLY|O_CREAT,0604))==-1) {
13. Změňte řádek ve zdrojovém textu programu v jazyce C
if((outf=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666))==-1) {
na
if((outf=open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666))==-1) {
Řešení by mělo fungovat pro libovolnou pozici kurzoru na řádku a bez použití
šipek (a jejich ekvivalentů h, l, space, backspace) a příkazu :s.
14. Napište příkaz, který otočí pořadí řádků v souboru (první bude poslední,
druhý předposlední, atd.).
15. Napište postup pro otočení pořadí znaků na řádku s kurzorem (z 'abcd'
udělá 'dcba') bez použití externího příkazu (tj. ne ':.!rev').
-------------------------------------------------------------------------------
F) regulární výrazy, grep
-------------------------------------------------------------------------------
1. Vypište řádky souboru /etc/passwd, které odpovídají informacím o
uživatelích - studentech se starým loginem (4 písmena následovaná 4
číslicemi).
2. V souborech s příponami .h, .c a .cc v aktuálním adresáři najděte direktivy
preprocesoru jazyka C pro definování maker. Řádky s těmito direktivami
začínají řetězcem '#define'
3. Najděte e výpisu získaném příkazem 'ls -l' všechny programy - spustitelné
soubory, které mají právo EXECUTE pro uživatele, skupinu i ostatní.
Nezapomeňte zahrnout do výpisu i SUID programy.
4. Najděte e výstupu příkazu 'mount' všechny podstromy připojené ze serveru
'ss1000'. Odpovídající řádky začínají jménem serveru ukončeným dvojtečkou,
např.
ss1000:/var/mail on /SPIS/mail type nfs (vers=2,dev=14000a)
5. Najděte ve výpisu adresáře příkazem 'ls -1p' všechny adresáře (za jménem
mají připojený znak '/') a symbolické linky (připojený znak '@').
6. Najděte e výstupu příkazu 'diff' řádky, které označují řádky obsažené jen v
jednom z porovnávaných souborů - na začátku řádku je '< ' (menšítko, mezera),
nebo '> ' (většítko, mezera).
7. Najděte v Postscriptovém souboru komentář obsahující počet stránek. Řádek s
tímto komentářem má tvar:
%%Pages: n
kde 'n' je dekadické číslo.
8. Najděte v souboru řádky končící dekadickým číslem.
9. Najděte v souboru řádky začínající hexadecimálním číslem: 0xN, kde N je
posloupnost číslic a písmen A-Z, a-z.
10. Najděte řádky souboru /etc/passwd, které odpovídají uživatelům skupiny
students (GID=200).
11. Najděte řádky souboru /etc/passwd, které odpovídají studentům (se starými
loginy), kteří mají správné UID. UID studenta se získá přidáním číslice 1 před
čtyřmístné číslo z login-name.
12. Najděte řádky souboru /etc/passwd, které obsahují informace o uživatelích
s domovskými adresáři v adresáři '/home'.
13. Najděte řádky souboru /etc/passwd, které odpovídají uživatelům s full name
obsahujícím aspoň dvě mezery, např. 'UNIX Lab Superuser', 'Rfind Daemon and
Fsdump,SGI'. Nezapomeňte, že regulární výraz musí specifikovat správné pole
záznamu v /etc/passwd.
14. Najděte řádky souboru /etc/group, které odpovídají skupinám s trojmístným
číslem skupiny.
15. Najděte řádky souboru /etc/passwd, které odpovídají uživatelům s username
o délce 3 až 7 znaků.
16. Najděte řádky souboru /etc/passwd pro uživatele se stejným UID a GID.
17. Najděte v seznamu souborů (získaném např. příkazem find) soubory, které v
cestě obsahují adresáře 'lib', nebo 'bin' a končí příponou '.so'.
18. Najděte ve výstupu příkazu 'ls -l' soubory, které mají stejná přístupová
práva pro vlastníka, skupinu a ostatní.
19. Najděte v konfiguračním souboru /etc/inetd.conf (konfigurace démona inetd)
všechny povolené síťové TCP služby. Popis každé služby je na samostatném
řádku, položky na řádku jsou oddělené libovolným počtem bílých znaků (mezery
nebo tabulátory, můžete uvažovat pouze mezery), řádky začínající znakem '#'
jsou komentáře. TCP služby mají ve 3. položce řetězec 'tcp'.
-------------------------------------------------------------------------------
G) ed, ex, sed
-------------------------------------------------------------------------------
1. Vytvořte skript pro editor ed, který vloží na začátek souboru 'skript'
řádek '#!/bin/bash' a zakomentuje (vloží '#' na začátek řádku) všechny bloky
řádků tvaru
/* ...
komentář
... */ ...
2. Vytvořte skript 'skript.sed' pro sed tak, že
sed -f skript.sed soubor.in > soubor.out
vloží na začátek souboru řádek '#!/bin/bash'
a zakomentuje (vloží '#' na začátek řádku) všechny bloky řádků tvaru
/* ...
komentář
... */ ...
3. Vytvořte skript pro editor ex, který v editovaném souboru nahradí všechna
malá písmena na začátku slova velkými a slova obsahující písmeno e nebo E
napíše celá velkými písmeny.
4. Napište emulátor 'turing.comp' Turingových strojů v editoru sed. Vstupem je
soubor 'turing.in', na každém řádku obsahuje jednu instrukci TS ve tvaru
qsQSM: q=stav (dekadické číslo), s=čtený symbol (libovolný znak kromě
metaznaků sedu, '_' je blank), Q=nový stav, S=nový symbol, M=pohyb -/0/+
(doleva, na místě, doprava). Začíná se s hlavou na začátku pásky ve stavu 0.
Definice TS může navíc obsahovat prázdné a kometářové řádky (začínají znakem
'#'). Příkazem
sed -f turing.comp turing.in > turing.out
se vygeneruje nový skript pro sed, pomocí
sed -f turing.out
se spustí simulace. Každý řádek vstupního souboru se bere jako jeden vstup pro
TS, simuluje se výpočet TS, vypisuje se konfigurace po každém kroku a nakonec
se vypíše výstup a pokračuje se dalším řádkem.
5. Pomocí sedu změňte C-čkové komentáře /* ... */ na C++-styl komentářů // ...
a naopak.
6. Pomocí sedu v souboru /etc/passwd přidejte k full-name studentů se starým
loginem (mají login name ve tvaru 4 písmena a 4 číslice) řetězec "student".
7. Napište skript pro editor ed, kterým ze shellového skriptu odstraníte
komentáře (řádky obsahující jen komentář budou zrušeny úplně, jinak bude
ponechán zbytek řádku před komentářem).
8. Pomocí editoru sed ze shellového skriptu odstraňte komentáře (řádky
obsahující jen komentář budou zrušeny úplně, jinak bude ponechán zbytek řádku
před komentářem).
9. Pomocí editoru sed změňte domovské adresáře uživatelů v /etc/passwd z
tvaru /afs/ms/uX/Xxxx na /home/Xxxx.
10. Pomocí editoru sed změňte domovské adresáře uživatelů v /etc/passwd z
/home/Xxxx na /afs/ms/uX/Xxxx (ve treti urovni se jmeno adresare sklada z 'u'
a prvniho pismene login name).
11. Pomocí editoru sed smažte z textu vše kromě prvního dekadického čísla na
každém řádku.
-------------------------------------------------------------------------------
H) expanzní znaky
-------------------------------------------------------------------------------
1. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
v aktuálním adresáři kromě souborů '.' (aktuální adresář) a '..' (rodičovský
adresář).
2. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny skryté
soubory (soubory, jejichž jméno začíná znakem '.') v aktuálním adresáři, kromě
souborů, které mají na druhém místě ve jménu velké písmeno.
3. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny zdrojové
soubory v jazyce C (soubory s příponou '.h' nebo '.c'), jejichž jméno začíná
velkým písmenem.
4. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny knihovny
(soubory se jménem začínajícím 'lib' a s příponou '.a' nebo '.so'.
5. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
se jménem dlouhým aspoň 3 znaky a končícím číslicí.
6. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
se jménem začínajícím písmenem 'S' nebo 'K', která následuje 2 číslice a pak
libovolný řetězec (takové soubory se vyskytují v adresářích /etc/rc?.d).
7. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny skryté
soubory (jejich jméno začíná '.'), které mají ve jménu číslici.
8. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
v prvních dvou úrovních stromu adresářů (tj. obsah adresáře '/' a adresářů v
něm (mimo skrytých souborů - se jménem začínajícím '.').
9. Pomocí expanzních znaků shellu zapište výraz, který vybere skripty, které
se spouštějí při startu nebo změně úrovně běhu systému, tj. soubory v
adresářích '/etc/rc<číslice>.d'.
10. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
s aspoň dvojznakovým jménem začínajícím velkým písmenem.
11. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
se jménem končícím trojznakovou příponou, jméno a přípona jsou oddělené tečkou
(např. soubor.txt).
12. Pomocí expanzních znaků shellu zapište výraz, který vybere zdrojové
soubory pro překladač C a objektové soubory (soubory s příponami '.c', '.h',
'.o').
13. Pomocí expanzních znaků shellu zapište výraz, který vybere skryté soubory
(jméno začíná '.'), které mají ve jménu znak podtržítko nebo minus.
14. Pomocí expanzních znaků shellu zapište výraz, který vybere všechny soubory
statických knihoven (jméno začíná 'lib' a končí '.a') v adresářích lib
nacházejících se v druhé úrovni stromu adresářů (např. /usr/lib nebo /big/lib).
-------------------------------------------------------------------------------
I) přesměrování, kombinování příkazů, proměnné v shellu, metaznaky
-------------------------------------------------------------------------------
1. Exit status řádku
cmd1 | cmd2
je exit status posledního příkazu v rouře, tj. cmd2. Jak lze donutit shell,
aby vracel exit status prvního příkazu roury?
2. Co udělá následující příkaz a proč?
find `find / -name '*bin*' -type d` -type f \( -perm -4000 -o -perm -2000 \) \
-exec ls -l {} \;
3. Napište skript pro spouštění příkazů pomocí e-mailu. Program dostane na
vstup dopis ve tvaru:
From:
Subject:
pustí příkaz a na vstup mu dá . Výstup příkazu (standardní i
chybový) a návratový kód pošle zpět na adresu .
4. Co udělá následující příkaz a proč?
a=1;b=2;{ a=LEVY;echo $a >&2;}|{ b=PRAVY;echo $b;tr 'A-Z' 'a-z';};\
echo "A=$a,B=$b"
Jak se liší od
a=1;b=2;{ a=LEVY;echo $a;}|{ b=PRAVY;echo $b;tr 'A-Z' 'a-z';};echo "A=$a,B=$b"
5. Co udělá následující příkaz a proč?
{ { { echo 1aaa;echo 2bbb >&2;} 3>&1 1>&2 2>&3|\
{ tr 'a-z' 'A-Z';echo 2tr >&2;} 2>&1 } 3>&1 1>&2 2>&3 }>out 2>err
6. Co udělá následující příkaz a proč?
find /*/lib \( -type f -o -type l \) | xargs stat
7. Co udělá následující příkaz a proč?
a=0;cat /etc/group|while read l;do a=`expr $a + 1`;done;echo $a
Jaká byla pravděpodobná zamýšlená funkce tohoto příkazu a jak by se měl příkaz
opravit?
8. Co udělá následující příkaz a proč?
a=a; b=b; { echo $a; a=$a$b; echo $a; cd /etc; } > x ; echo $a
Jak se liší od
a=a; b=b; ( echo $a; a=$a$b; echo $a; cd /etc ) > x ; echo $a
9. Co udělá následující příkaz a proč?
{ cat a;cat b;cat c; }>out
Jak se liší od
cat a>out;cat b>out;cat c>out
-------------------------------------------------------------------------------
J) řídicí struktury, test, expr, eval, signály
-------------------------------------------------------------------------------
1. Co udělá následující příkaz a proč?
while read f out;N=`expr $N + 1`;done
Čím se liší od příkazu:
N=0;while [ $N -lt 10 ];do echo $N;N=`expr $N + 1`;done>out
5. Napište, příkaz (skript), který dostane 2 parametry DIR a USER a vypíše
velikost diskového prostoru, který v podstromu DIR zabírá uživatel USER.
6. Napište, příkaz (skript), který pro každého uživatele vypíše jeho
login-name, jmého jeho skupiny, full-name a vsechny jeho procesy setříděné
sestupně podle čísla procesu.
7. Napište, příkaz (skript), který vypisuje všechny skupiny a pro každou
skupinu seznam login-names uživatelů, kteří do ní patří (uživatelé, kteří jsou
uvedeni v příslušném řádku /etc/group a uživatelé, kteří mají skupinu
nastavenou jako primární v /etc/passwd). Jména uživatelů jsou oddělena
mezerami.
8. Napište, příkaz (skript), který pro každého uživatele vypíše jeho
login-name a počet a celkovou velikost jím vlastněných souborů v adresářích
'/tmp' a '/var/tmp'.
9. Napište, příkaz (skript), který pro každého nalogovaného uživatele vypíše
jeho login name, full name a jména terminálů, kde je nalogovaný. Záznam by měl
být na jedné řádce ve tvaru: 'login:full:term1,term2,term3,...'.
10. Napište, příkaz (skript), který kontroluje, zda všechny svazky uvedené v
/etc/fstab jsou připojené na správných adresářích (zjistíte ze souboru
/etc/mtab nebo příkazem mount). Vypisuje jména svazků, které nejsou správně
připojené a adresář, kam by měly být připojené (podle /etc/fstab).
11. Napište, příkaz (skript), který vypisuje plná jména uživatelů, kteří jsou
právě nalogovaní (pro zjištění nalogovaných uživatelů použijte příkaz who).
Každého uživatele vypisuje pouze jednou.
12. Napište, příkaz (skript), který před každý parametr počínaje třetím vloží
řetězec, zadaný jako druhý parametr, a takto modifikovaný seznam parametrů
předá příkazu, který je zadaný jako první parametr. Tj. např. 'PARAMS cmd -x 1
2 3' zavolá příkaz 'cmd -x 1 -x 2 -x 3'.
13. Napište, příkaz (skript), který čte řádky ze vstupu, rotuje je vlevo o
počet slov zadaných jako parametr a výsledné řádky vypisuje. Např. s
parametrem '2' řádek 'a b c d e' vypíše jako 'c d e a b'.
14. Napište, příkaz (skript), který zkopíruje všechny soubory v aktuálním
adresáři, které mají příponu '.c', do souborů se stejným jménem a příponou
'.bak'.
15. Napište, příkaz (skript), který vypisuje obsah adresáře, který dostane
jako parametr. Když narazí na jméno podadresáře, zeptá se uživatele, zda má
vypsat obsah podadresáře. Podle odpovědi ho buď vypíše, nebo přeskočí. Pracuje
rekurzivně, tj. ptá se i na podadresáře podadresářů.
16. Napište, příkaz (skript), který vypíše seznam všech manuálových stránek,
které jsou v sekci zadané jako 1. argument a jejich názvy začínají řetězcem
zadaným ve 2. argumentu. Adresáře s manuálovými stránkami jsou uvedeny
(oddělené dvojtečkou) v proměnné MANPATH, jednotlivé sekce jsou v
podadresářích 'man<č. sekce>'. Soubory s manuovými stránkami mohou mít různé
přípony. Vypisujte pouze jména (setříděná podle abecedy), ne cesty ani
přípony.
17. Napište, příkaz (skript), který dostane jako parametr jméno souboru, ve
kterém je na každém řádku jméno souboru. Jednotlivá jména jsou postupně
nabízena uživateli, který si může u každého souboru vybrat jednu z akcí: X
(konec skriptu), L (zobrazit obsah souboru, po zobrazení se opět zeptá na akci
pro stejný soubor), R (smazat soubor), N (další soubor).
18. Napište, příkaz (skript), který výstup příkazu 'ls -l' upraví tak, že
vypisuje jen plné jméno vlastníka souboru, číslo jeho skupiny a jméno souboru.
19. Co udělá následující příkaz a proč?
i=1;a1=A;a2=B;a3=C;b=`eval echo \\\$a\`expr $i + 1\``;echo $b
20. Napište, příkaz (skript), který vypíše (setříděná podle abecedy) jména
všech programů, které můžete spustit bez udání plné cesty (tj. všechny soubory
v adresářích napsaných v proměnné $PATH, ke kterym máte právo execute)?
-------------------------------------------------------------------------------
K) awk
-------------------------------------------------------------------------------
1. Napište awk skript, který dostane jako parametr jméno HTML dokumentu
a vypíše všechny URL, na které z daného dokumentu vedou odkazy. Předpokládejte
odkazy ve tvaru , kde 'A HREF' může být libovolná kombinace
malých a velkých písmen.
2. Napište awk skript, který v textu zakomentuje všechny odstavce, které
začínají komentářovým řádkem. Znak uvozující komentář je zadán jako argument,
odstavce se oddělují prázdným řádkem.
Př. (\n je znak konce řádku)
# radek 1 # radek 1
radek 2 # radek 2
radek 3 --> # radek 3
\n \n
odstavec 2 odstavec 2
3. Napište awk skript, který formátuje text po odstavcích (oddělují se prázdným
řádkem) do zadaného počtu sloupců. Program vždy vezme odstavec a napíše ho na
co nejmenší počet řádků tak, aby k přechodu na nový řádek nedocházelo
uprostřed slova.
4. Napište skript pro shell+awk, který simuluje chování příkazu head.
Rozpoznejte přepínač -n udávající počet vypisovaných řádek. Shell použijte jen
pro zpracování parametrů pro awk. Napište totéž pro gawk (bez shellu, s
využitím proměnných ARGC, ARGV v gawk).
5. Implementujte zásobníkový kalkulátor pomocí awk. Kalkulátor čte ze vstupu
a zpracovává příkazy:
p ... vytiskne vrchol zásobníku
e ... smaže vrchol zásobníku
a číslo ... vloží číslo na vrchol zásobníku
d ... zduplikuje číslo na vrcholu zásobníku
+ ... vezme ze zásobníku číslo pod vrcholem a na vrcholu, sečte je a výsledek
vloží na zásobník
- ... vezme ze zásobníku číslo pod vrcholem a na vrcholu, odečte je a výsledek
vloží na zásobník
* ... vezme ze zásobníku číslo pod vrcholem a na vrcholu, vynásobí je a
výsledek vloží na zásobník
/ ... vezme ze zásobníku číslo pod vrcholem a na vrcholu, vydělí je a výsledek
vloží na zásobník
w prom ... uloží číslo na vrcholu zásobníku do proměnné prom
r prom ... vloží na zásobník obsah proměnné prom
s ... zobrazí celý zásobník
Chybný příkaz způsobí vypsání '?'. Pozor na kontrolu prázdného zásobníku a
dělení nulou.
6. Napište skript pro awk, který simuluje chování příkazu tail v základní
formě bez přepínače pro počet řádků, tj. vždy vypíše posledních 10 řádků
souboru.