Abychom se vyhli opakování stejného kusu kódu, můžeme si nějaké funkční celky uzavřít do funkcí, které následně budeme volat. Funkce se také občas hodí k tomu, abychom neměli zbytečně dlouhý kus kódu. V neposlední řadě se hodi ke zkoušce, protože na papíře se špatně vkládá několik řádků.
#!/bin/sh
funkce() {
echo ahoj!
echo já jsem funkce "$0" a byla jsem zavolána s "$#" parametry.
echo Například druhý parametr má hodnotu: "$2".
echo také vím, že mám dostat parametr v proměnné vstup. Jeho hodnota je následující: "$vstup"
echo Protože jsem hodná, tak na výstup uložím o jedna vyšší číslo:
vystup="$(( vstup + 1 ))"
echo
}
funkce 1 2 3
echo $vystup
vstup=6
funkce 1 2 3
echo $vystup
Co se traduje: Za šipky na papíře údajně Forst vyhazuje od zkoušky. Pokud použijete funkci, je to ok.
"$*" a "$@"? Vysvětlete...
Mějme skript:
#!/bin/sh
funkce() {
echo prvni parametr je: "$1"
echo druhy parametr je: "$2"
echo treti parametr je: "$3"
echo ctvrty parametr je: "$4"
}
funkce "$@"
echo
funkce "$*"
echo
funkce $@
echo
funkce $*
A zkusme si jej spustit:
./skript.sh "1. argument" "2. argument" "3. argument" "4. argument"
find, ls -R).
Zkuste to udělat tak, že jako jeden z argumentů dostanete maximáľní povolenou hloubku zanoření.
# Příklad testovacích dat: mkdir -p test/prvni/druha/treti/ctvrta/pata/sesta mkdir -p test/prvni/druha/treti/ctvrta/pata/sesta2 mkdir -p test/prvni/druha/treti2/ctvrta/pata/sesta mkdir -p test/prvni/druha/treti2/ctvrta/pata2/sesta mkdir -p test/prvni2/druha mkdir -p test/prvni2/druha2 mkdir -p test/prvni2/druha3/treti mkdir -p test/prvni2/druha3/treti2 mkdir -p test/prvni2/druha4
Aspoň na Linuxu je rozdíl mlhavý -- jednotlivá vlákna od sebe mohou být různě izolovaná a od určité míry izolace to už nazveme jako separátní proces.
Interaktivní příkazy: top, htop.
Důležité: PID, PPID, init proces (PID 1)
Pouštění příkazu na pozadí pomocí &
Příkazy fg, bg, jobs, pozastavení pomocí Ctrl+Z
Ukázali jsme si exec (Ale příliš jsme si nevysvětlili podobu s vytvořením nového procesu (fork & exec).
Ukázali jsme si wait a $!
max, která najde maximum ze svých argumentů. Tou se pak dá sleep sort rozšířit: wait na konci bude čekat jen na ten proces, který byl volaný s maximálním argumentem. Využití: takto přímo asi nulové, ale aspoň je to dobře definovaná úloha, kterou si člověk může vyzkoušet
Jen řešeno ve spěchu, neukázali jsme si příklady v terminálu. Ale občas někdo exit použil...
Napište si vlastní funkci, která bude fungovat jako taková podmínka. Dostane jako argument soubor a uspěje, pokud se v daném souboru nevyskytuje slovo bagr. (Pokud soubor neexistuje, nebo je to adresář, podmínka neuspěje.)
$?
Jestli zbyde čas, tak zkrácené vyhodnocování && || (nezbyl)
Procesy si navzájem mohou posílat signály (obdoba Interruptů – přeušení, viz principy počítačů).
# Údajně POSIX definuje následující (neověřoval jsem si): 1 SIGHUP (hang up) 2 SIGINT (interrupt) 3 SIGQUIT (quit) 6 SIGABRT (abort) 9 SIGKILL (kill) 14 SIGALRM (alarm) 15 SIGTERM (terminate) # Důležité podle mě: jméno číslo popis -------------------------------------------------------- SIGINT To co pošle Ctrl+C SIGKILL (9) Nelze se mu bránit, zabije proces SIGHUP Zavření terminálu (pro daemony načtení konfigurace) SIGTERM Měkké ukončení -- posílá se automaticky pří vypínání systému všem procesům, po nějakéĺ timeoutu se pošle SIGKILL SIGTSTP To, co posílá Ctrl+Z, zastavení procesu SIGCONT Rozběhnutí procesu SIGCHLD Tento signál obdrží proces, když doběhne nějaký jeho potomek
wait $PID $!
Tipické využití: kopíruji si disk pomocí dd, chci znát průběh, pošlu mu signál SIGUSR1
Chci ukončit nějaký konkrétní proces, zavolám kill "$pid". Pokud vzdoruje, pošľu mu SIGKILL: kill -9 "$pid".
Pro pokročilé: příkaz pkill
Chci-li signál odchytit v shellu, použiji trap příkaz signál
#!/bin/sh
zpracovavej_data () {
echo "Vypisuji cislo $1 do souboru $docasny_adresar/$1.temp"
echo "$1" > "$docasny_adresar/$1.temp"
sleep 1
}
docasny_adresar="`mktemp -d`" # mktemp není v POSIXu, na zkoušce si jej možná budete muset naprkogramovat sami, ale pro reálný život je moc užitečný
echo "Ahoj! Jsem skript, který si právě založil dočasný adresář $docasny_adresar"
echo "Teď do něj jdu ukládat svá data..."
seq 40 | while read number; do
zpracovavej_data "$number"
done
rm -rf "$docasny_adresar"
Doplňte do něj pomocí trap takovou funkcionalitu, aby při předčasném zabití skriptu pomocí Ctrl+C došlo k pročištění dočasných souborů.
Zde se budou průběžně objevovat případné skripty či vstupy a výstupu, které napíšeme na projektoru.