$ cat akt_baze1 : # Aktualizace databáze baze1. Klíčový parametr jmeno $EDITOR baze1 echo "`date` $jmeno`" >> baze1 # $ jmeno=KarelIV akt_baze1
eval řetězcový_výraz
Př.
Scénář vypis vypíše stránkovaný obsah aktuálního adresáře v krátkém nebo dlouhém formátu.
$ cat vypis : # Použití: vypis typ # typ=k krátký formát # typ=d dlouhý formát typ_prikazu_k=ls typ_prikazu_d="ls -l" eval \$typ_prikazu_$1
nohup cc *.c &
if příkaz1
then
:
else
příkaz2
fi
if příkaz1 then příkaz2 fi
if seznam_příkazů
then
seznam_příkazů
fi
if seznam_příkazů
then
seznam_příkazů
else
seznam_příkazů
fi
if seznam_příkazů
then
seznam_příkazů
elif seznam_příkazů
seznam_příkazů
...
else
seznam_příkazů
fi
Př.
case $teplota in
vysoká | střední ) echo Zavři topení ;;
velmi_vysoká) echo Zavři topení a otevři okno ;;
obrovská) echo Vyskoč z okna ;;
nízká | velmi_nízká) echo Otevři topení ;;
*) echo Vše v pořádku
esac
| -r soubor | pravda, pokud soubor existuje a uživatel pro něj právo čtení |
| -w soubor | pravda, pokud soubor existuje a uživatel pro něj právo zápisu |
| -w soubor | pravda, pokud soubor existuje a uživatel pro něj právo spouštění |
| -f soubor | pravda, pokud soubor existuje a je obyčejným souborem |
| -d soubor | pravda, pokud soubor existuje a je adresářem |
| -c soubor | pravda, pokud soubor existuje a je speciálním znakovým souborem |
| -b soubor | pravda, pokud soubor existuje a je speciálním blokovým souborem |
| -p soubor | pravda, pokud soubor existuje a je pojmenovanou rourou |
| -s soubor | pravda, pokud soubor existuje a má nenulovou délku |
| -t [fd] | pravda, je-li na daném terminálu otevřen soubor s popisovačem fd. Standardně fd=1. |
| -n s1 | pravda, má-li řetězec s1 nenulovou délku |
| -z s1 | pravda, má-li řetězec s1 nulovou délku |
| s1 = s1 | pravda, jsou-li řetězce s1 a s2 totožné |
| s1 != s2 | pravda, jsou-li řetězce s1 a s2 různé |
| s1 | pravda, není-li s1 prázdný |
| n1 -gt n2 | pravda, je-li celé číslo n1 větší než celé číslo n2 |
| n1 -ge n2 | pravda, je-li celé číslo n1 větší nebo rovno celému číslu n2 |
| n1 -lt n2 | pravda, je-li celé číslo n1 menší než celé číslo n2 |
| n1 -le n2 | pravda, je-li celé číslo n1 menší nebo rovno celému číslu n2 |
Operátory v pořadí klesající priority
Scénář najdis má parametry počáteční adresář a jméno souboru. Najde všechny soubory se zadaným jménem v podstromu adresářů, od počátečního adresáře. Pro každý soubor vytiskne jeho úplnou cestu, přístupová práva pro aktuálního uživatele a typ souboru.
$ cat najdis
#!/bin/sh
if test $# != 2
then
echo "Pouziti: $0 adresar prikaz" 1>&2
exit 1
fi
if [ ! -d $1 ]
then
echo "$1 neni adresar" 1>&2
exit 2
fi
cesta=""
cesta=`find $1 -name $2 -print 2>/dev/null`
if [ -z "$cesta" ]
then
echo "Soubor $2 nenalezen"
exit 3
fi
for nalezena_cesta in $cesta
do
clear
echo
echo "VYSLEDKY HLEDANI"
echo
echo "*****************************************************************"
echo
echo "Uplna cesta k souboru $2 je $nalezena_cesta"
[ -d $cesta ] && echo "soubor je adresar"
[ -r $cesta ] && echo "soubor je citelny pro uzivatele $LOGNAME"
[ -w $cesta ] && echo "uzivatel $LOGNAME muze do souboru psat"
[ -x $cesta ] && echo "uzivatel $LOGNAME muze soubor spoustet"
echo
echo "typ souboru `file $nalezena_cesta`"
echo
echo "*****************************************************************"
echo
tput smso; echo "Enter dalsi nalezeny soubor, k konec"
tput rmso; read dalsi
if [ "$dalsi" = k ] -o [ "$dalsi" = K ]
then
exit
fi
done
Vyvolání pro všechny soubory .profile v adresáři /home
$ najdis /home .profile
until seznam_příkazů
do
seznam_příkazů
done
Cykly while a until mají testy na začátku
for proměnná in seznam_slov
do
seznam_příkazů
done
Př .
Postupné vyvolání manuálu pro Bourův shell, C-shell, a Kornův shell:
for druh_shellu in sh csh ksh do man $druh_shellu done
Př.
Pro všechny soubory,jejichž jména jsou zadané jako argumenty scénáře přidáme na konec souboru celek:
for cast do cat cast >> celek done
Př.
O souborech začínajících řetězcem ucet v aktuálním adresáři chceme zobrazit údaje z dlouhého formátu příkazu ls a - prvý a poslední řádek každého souboru po stránkách
$ {ls -l ucet*; head -1 ucet*; tail +1 ucet*;} | more
Př.
Je třeba opravit a přeložit v adresáři $HOME/apl1/zdrojc programy v jazyce C tak, abychom po skončení této práce byli opět v původním adresáři:
$ ( cd $HOME/apl1/zdrojc; vi *.c; cc *.c;)
To je evivalentní posloupnosti:
soucasny_adresar=`pwd` cd $HOME/apl1/zdrojc vi *.c cc *.c cd $soucasny_adresar
Př.
Skript kopie vytvoří záložní kopii souborů, jejichž jména se zadávají jako argumenty:
$ cat kopie
#!/bin/sh
#
# Funkce pouziti vytiskne napovedu a nastavi kod navratu 1
#
pouziti()
{
echo "Pouziti: $0 soubor..." 1>&2
exit 1
}
#
#Funkce zaloha zkopiruje soubor do soubor.bak
zaloha()
{
for soubor
do
cp $soubor ${soubor}.bak
done
}
#
if [ $# -lt 1 ]
then
pouziti
exit 1
fi
while [ $1 ]
do
soubory="$soubory $1"
shift
done
zaloha $soubory
Vyvolání skriptu kopie pro zálohu všech dat v aktuálním adresář s trasováním:
$ sh - x kopie *Scénář vpravo (vlevo) posune všechny řádky souboru zadaného jako argument o tabulátor vpravo (vlevo) a vypíše jej.
$ cat vpravo
:
if [ $# != 1 ]
then
echo "Pouziti: $0 soubor" 1>&2
exit 1
fi
ex -s $1 <<KONEC
%>>
x
KONEC
more $1
$ cat vlevo
:
if [ $# != 1 ]
then
echo "Pouziti: $0 soubor"
exit 1
fi
ex -s $1 <<KONEC
%<<
x
KONEC
more $1
Vyvolání scénářů
$vpravo pako $vlevo pako
$ cat inputi
#!/bin/sh
#
# Cteni celeho cisla bez znamenka z klavesnice s kontrolou
#
while true
do
echo -n "Cislo= " > /dev/tty
#
# Presmerovani na terminal pro pouziti ve tvaru
# promenna=`inputi`
#
# Neni-li na systemu volba -n, pak zkus nasledujici
#
# echo "Cislo= "\\c > /dev/tty
#
# Pokud i toto nepracuje, napis napr. vlastni napr.
#
# echon()
# {
# echo $1 | tr -d '
#'
# }
#
read cislo
if expr "$cislo" : "[0-9 ]" > /dev/null 2>/dev/null
then
break
else
echo "Chybny znak v cisle" > /dev/tty
fi
done
echo $cislo
Procesu s číslem pid lze explicitně zaslat signál (přerušení) příkazem
kill [signál] pid;
některé signály se generují stiskem speciálních kláves.
íScénář může odchytit signál ( přerušení) a zpracovat jej či potlačit příkazem trap:
Nejdůležitější čísla signálů:
| 0 | ukončení shellu ( příkaz exit nebo při chybě shellu) |
| 1 | HANGUP (odpojení terminálu) |
| 2 | INTERRUPT (stisknutí klávesy |
| 3 | QUIT (stisknutí kláves |
| 9 | KILL ( zrušení procesu) |
| 11 | chyba v adresování paměti (memory fault) |
| 15 | požadavek na terminál |
Signály 9 a 11 nelze potlačit a není možné změnit standardní reakce příkazem trap.
Př..
Každý scénář, který zakládá dočasné soubory by měl jako elementární požadavek slušnosti je po sobě uklidit před normálním ukončením či při nuceném přerušení:... docasny_soubor=/tmp/pom_seznam$$ touch docasny_soubor trap 'rm -f $docasny_soubor; exit' 0 1 2 3 15 ...
Př..
Příklad složitějšího scénáře - manažer pro práci se soubory
Úkolem je napsat scénář msoub, který řeší tyto základní práce se soubory:
$ cat msoub
#!/bin/sh
#
# Scénář msoub pro manipulaci se soubory
#
# Příkazy: oprava, prohlídka, tisk, vymazání se zadávají
# stisknutím počatečního písmena (nerozlišují se malá a # velká) a klávesy Enter
# Použití: msoub soubor...
#
# Funkce pouziti vytiskne nápovědu při nesprávném zadání
#
pouziti()
{
echo " Použití: $0 soubor..."
}
#
# Funkce navod vytiskne návod k ovládání menu
#
navod()
{
#
clear
tput cup 3 5; tput smso;
echo " M A N I P U L A C E S E S O U B O R Y"; tput rmso
tput cup 4 5
echo _________________________________________________
tput cup 5 25; tput smso;
echo -n "SOUBOR: "; tput rmso; echo $soubor
tput cup 7 5; tput smso
tput smso; echo -n O; tput rmso; echo -n "prava "
tput smso; echo -n P; tput rmso; echo -n "rohlídka "
tput smso; echo -n T; tput rmso; echo -n "isk "
tput smso; echo -n V; tput rmso; echo -n "ymazání "
tput smso; echo -n D; tput rmso; echo -n "alší "
tput smso; echo -n K; tput rmso; echo -n "onec "
tput cup 9 5
echo _________________________________________________
tput cup 11 5
echo -n "Vyber funkci prvním písmenem + Enter: "
}
#
if [ $# -lt 1 ]
then
pouziti; exit 1
fi
for soubor in $*
do
if [ ! -f $soubor ]
then
echo "$soubor neexistuje"
fi
while true
do
navod; tput smso
read odpoved dalsi; tput rmso
case $odpoved in
[Oo]) vi $soubor;;
[Pp]) vi -R $soubor;;
[Tt]) lp $soubor;;
[Vv]) rm -i $soubor;;
[Dd]) break;;
[Kk]) break 2;;
*) ;;
esac
done
done
Scénář má řadu nevýhod, dstranění jako cvičení - např.:
Na rozdíl od komentáře uvozeného # se komentář za : chápe jako argument a k zamezení případných náhrad bude někdy třeba text uzavřít do apostrofů či uvozovek.
Provede v aktuálním shellu příkazy zadané v argumentu.
Vytiskne sumární uživatelské a systémové časy běžícího procesu.
Př.
nazev_souboru='funkce.4GL' pocet_znaku=`expr "$nazev_souboru" : '.*\.\
Př.
echo ${datum:-`date`}
echo ${TERM:=vt102}
echo ${INFORMIXDIR:?"Proměnná nenastavena"}
echo ${INFORMIXDIR:?}
datum=`date`}
echo ${datum:+"Na svatýho Dyndy!}