Č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
echo
nebols
) - 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
,top
nebohtop
) - 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í
wc
počí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.