Čtrnácté cvičení – Dodělání AWK, zbytky shellu (funkce, signály, procesy)
Navážeme na AWK z minulého cvičení. A pak věci, co nám v shellu různě zbyly jako funkce, signály, procesy.
Základy AWK:
Zobrazit/skrýt základy AWKDodělání AWK
Lepší matchování
Matchovat se lze i jenom na některý field záznamu a to konstrukcí $1 ~ /.../.
A vzory lze také kombinovat pomocí && a || a negovat !:
$3 ~ /^Volkswagen/ # Matchují záznamy se třetím sloupce začínajícím na "Volkswagen"
$3 !~ /^Volkswagen/ # Všechny ostatní
!/^#/ # Nezakomentované řádky
/^#/ || $3 ~ /^Volkswagen/ # Záznamy buď celé zakomentované, nebo se třetím sloupce začínajícím na "Volkswagen"
Funkce v AWK
function minimum(pole, min) {
min = pole[0]
for (i in pole) {
if (pole[i] < min) min = pole[i]
}
return min
}
Pozor, nedají se v nich definovat lokální proměnné (ale dá se použít trik s neuvedenými proměnnými v hlavičce).
Dodělávky v shellu:
Aliasy
Jednoslovné zkratky usnadňující práci v shellu.
alias p='python3' # Nastaví alias
alias p # Vypíše alias
alias # Vypíše všechny aliasy
Funkce
- Vše je globální (funkce samotné i proměnné)
- Parametry dostávají jako shellový skript (v
$1, $2, ..., všechny parametry v$@a jejich počet v$#) - Nevhodnou volbou jména si lze skrýt jiné věci (není asi dobrý nápad pojmenovávat funkci
echonebols) - Vrací jen návratovou hodnotu pomocí
return(pokud není zavoláno, je to 0) - Pokud chceme vrátit nějaký string, tak ho vypíšeme a při volání použijeme
vysledek=$(funkce 1 2 3)
hello () {
echo "Hello $1."
}
nactiHeslo() {
printf "Zadej heslo: " 1>&2
read passwd
echo "$passwd"
}
heslo=$(nactiHeslo)
Signály
- Signály lze zasílat běžícím procesům
- V momentě zachycení dojde k přerušení běhu a nejdříve se obslouží signál
- Pokud není program ukončen, tak po obsloužení pokračuje v běhu na původním místě
POSIXové signály:
$ kill -l
1 SIGHUP # hang up - třeba po rozpadnutí SSH spojení (u démonů se používá pro znovunačtení konfigurace)
2 SIGINT # interrupt - posílá ho třeba Ctrl-C
3 SIGQUIT # quit - posílá ho Ctrl-\
6 SIGABRT # abort
9 SIGKILL # kill - nelze odchytit, následuje nenávratná a okamžitá smrt procesu
14 SIGALRM # alarm
15 SIGTERM # terminate - požádání o ukončení běhu
Mimo SIGKILL lze signály odchytávat pomocí trap '<příkazy>' <signály>,
často se místo příkazů používá volání nějaké funkce.
trap '' INT # Zablokuje SIGINT (na Ctrl-C neudělá nic)
trap 'echo "Koncim"' TERM # Před koncem programu se rozloučí
trap 'funkce' INT QUIT # Lze volat i funkci a nastavit stejný trap pro více signálů
Posílání signálu procesům
- Zjistit PID procesu (třeba pomocí
ps,topnebohtop) - Zavolat třeba
kill -9 PID - Užitečný pro zjištění PID je i
pgrep nazev_programu - Může se hodit i
killall nazev_programu - Napište v AWK vlastní
wcpočítající počet řádků, počet slov a počet znaků a vypište je na konci. - Vymyslete awk skript/příkaz, který bude mazat nadbytečné prázdné řádky – tedy každou posloupnost za sebou jdoucích prázdných řádků změní na jediný prázdný řádek.
- Napište program, který vypíše jméno signálu, který mu byl zaslán a běží dál bez ukončení (stačí standardní
POSIXové signály). Posílejte tomuto programu různé signály pomocí
kill, abyste vyzkoušeli jeho chování. - Napište program, který dostane jako parametr nějaký regex a pak bude číst standardní vstup (třeba bude
dostávat stream z Twitteru :-)).
Pokud při čtení někde objeví slovo vyhovující regexu, tak si ho i s časem zapíše do pomocného souboru. Ve chvíli, kdy dostane SIGINT nebo SIGTERM, tak pomocný soubor před ukončením vypíše a smaže.