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.