U N I X
Autor : ing. Ales Limpouch, KP FEL CVUT Praha

5. Programovani v shellu

Shell neni pouze interpretem prikazovych radku, ale i velmi
vykonnym programovacim jazykem. Programove konstrukce lze
zadavat primo z prikazoveho radku nebo za pouziti prikazoveho
souboru (scenare - script file) - viz kap. 3.2. Protoze mnoho
prikazovych souboru je vytvoreno pro Bourne shell, je schopen
C-shell spustit pro interpretaci prikazoveho souboru Bourne shell.

Pro odliseni, zda je scenar urcen pro Bourne shell nebo C-shell,
se pouziva prvniho znaku prvniho radku souboru. Je-li tento znak
#, potom je interpretovan scenar C-shellem, jinak Bourne shellem.
V systemech s obema typy shellu lze doporucit pro praci C-shell,
ktery je pohodlnejsi a mocnejsi nez Bourne shell. Pri tvorbe
vetsich programovych celku lze vsak spise z duvodu prenositelnosti
doporucit psani prikazovych souboru v Bourne shellu.


5.1 Spusteni shellu

Prikazy pro spusteni shellu byly jiz uvedeny v odstavci 3.3.
Zde pouze poznamenejme, ze po prihlaseni do systemu interpretuje
shell automaticky prikazovy soubor .login (pro C-shell)
nebo .profile (pro Bourne shell) v domovskem adresari uzivatele.
Tento soubor lze vyuzit pro spusteni uzivatelskeho prostredi
a spusteni neketrych zakladnich procesu. Pri aktivaci shellu
(napr. prikazem csh) se automaticky provede soubor .cshrc
(pro C-shell). Dale je zde vhodne upozornit, ze pro docasne
pomocne soubory lze pouzit i adresar /tmp.


5.2 Specialni znaky shellu

Existuji znaky, ktere maji pri interpretaci shellem specialni
vyznam. Na nektere jsme jiz narazili v odstavcich 1, 2.1 a 3.1
a 3.2.

Pouzitelne znaky se specialnim vyznamem:

\ viz kap. 1 (potlacuje spec. vyznam)
*, ?, [] viz kap. 2.1
>, >>, &>, <, <<,
<&, |, |& viz kap. 3.1
;, &, () viz kap. 3.2
`...` nahrada prikazu ... vystupem ... (spusteni!)
'...' potlacuje interpretaci znaku uvnitr ...
"..." interpretuje jen $ a `...`
: interpretace bez vykonani akci
# na 1.pozici radku oznacuje komentar

{ } provedeni posloupnosti prikazu bez spusteni
kopie shellu (pouze Bourne shell)
{...,...} vycet variant jmena souboru (pouze C-shell)
~ domovsky adresar (pouze C-shell)


5.3 Promenne shellu

Jako kazdy programovaci jazyk umoznuje shell pracovat
s promennymi, ktere vytvareji tzv. prostredi uzivatele
a prostredi procesu. Nektere promenne jsou v systemu
preddefinovany, prip. mohou byt definovany pri spusteni
shellu. Jmeno promenne je identifikator.

C-shell povazuje pouze promenne oznacene velkymi pismeny
za soucast prostredi uzivatele. Ostatni (napr. argv, home,
path, prompt, shell ap.) povazuje za sve vnitrni promenne.

Prace s promennymi:

Bourne shell :

name = con prirazeni retezce con promenne name
unset varname zruseni promenne
set vypis hodnot promennych
$name zpristupneni hodnoty promenne

preddefinovane promenne prostedi a procesu:
MAIL jmeno souboru pro elektronickou postu
HOME jmeno domovskeho adresare
PATH adresare se spustitelnymi prikazy
LOGNAME prihlasovaci jmeno uzivatele
SHELL aktivni prikazovy interpret
TERM typ terminalu
PS1 retezec vyzvy
PS2 pokracovaci vyzva (pri nedokoncenem vstupu)
IFS oddelovace argumentu prikazoveho radku
0,1,2,..,9 pozicni parametry (tj. argumenty) prikazu
(0 .. jmeno prikazu)
$ PID soucasne kopie shellu
? navratovy kod posledniho provedeneho prikazu
! PID posledniho procesu spusteneho na pozadi
* obsah celeho prikazoveho radku scenare
# pocet pozicnich parametru scenare
 

C-shell :

set name = str prirazeni retezce str vnitrni promenne name
set name = ( strs ) prirazeni seznamu retezcu strs
vnitrni promenne varname
setenv varname str prirazeni retezce str promenne varname
z prostredi uzivatele
unset varname zruseni promenne
unsetenv varname zruseni promenne
$?varname test existence promenne
set vypis hodnot promennych
$name zpristupneni hodnoty promenne
setenv vypis hodnot promennych prostredi
$varname[num] zpristupeni casti seznamu pomoci indexu num
$#varname pocet prvku v seznamu

pro promenne obsahujici uplne jmeno souboru
lze uzit operatoru:
:r uplne jmeno souboru (root)
:h path (header)
:t proste jmeno souboru (tail)

preddefinovane promenne shellu:

prostredi :
argv preddefinovany promenna predstavujici
seznam argumentu scenare (pristup
jako do pole - rozsahy indexu)
cwd pracovni adresar
history delka uchovavane historie
home jmeno domovskeho adresare
noclober ochrana souboru pred prepsanim (presmerovani)
path adresare se spustitelnymi prikazy
prompt retezec vyzvy
shell aktivni prikazovy interpret
status navratovy kod posledniho procesu
term typ terminalu
user prihlasovaci jmeno uzivatele
MAIL jmeno souboru pro elektronickou postu
HOME jmeno domovskeho adresare
PATH adresare se spustitelnymi prikazy
LOGNAME prihlasovaci jmeno uzivatele
SHELL aktivni prikazovy interpret
TERM typ terminalu

procesu :
0,1,2,..,9 pozicni parametry (tj. argumenty) prikazu
(0 .. jmeno prikazu)
$ PID soucasne kopie shellu


5.4 Programove konstrukce shellu

Shell poskytuje konstrukce pro vetveni typu if a case a pro
cykly typu for, while i until. Pro rozhodovaci vyrazy tyto
konstrukce vyuzivaji navratoveho kodu prikazu, ktery je bud
nulovy (prikaz skoncil uspesne) nebo nenulovy (selhani).
Pro vyhodnocovani nekterych typu vyrazu existuji dva pomocne
prikazy test a expr. V C-shellu existuji i numericke promenne
(viz odstavec 5.5), ktere jsou vyuzivany pri konstrukci vyrazu.
Vyraz lze zapisovat jako bezny prikaz v jazyce C a navic lze
testovat atributy souboru pomoci operatoru shodnych s moznymi
argumenty prikazu test.

Programove konstrukce shellu:

Bourne shell C-shell

if cmdlist if (expr) then
then cmdlist cmdlist1
else cmdlist else
fi cmdlist2
endif
case str in switch (str)
pattern) cmdlist ;; case pattern1:
... cmdlist
esac breaksw
...

default:
cmdlist
breaksw
endsw

for var in strs foreach name (strs)
do cmdlist
cmdlist end
done

while cmdlist while (expression)
do cmdlist
cmdlist end
done

break break ukonceni cyklu
continue continue nasledujici iterace
exit exit ukonceni shellu
goto label skok na navesti

label: definice navesti
read name set name = $< precteni promenne name
ze std.vstupu

Dalsi operatory (oddelovace) pro cmdlist:

&& prava strana se provede pokud leva uspeje
|| prava strana se provede pokud leva selze

Pomocne prikazy:

test arg navratovy kod je dan vyhodnocenim vyrazu arg
-r file existuje soubor dostupny pro cteni
-w file existuje soubor dostupny pro zapis
-f file existuje soubor a neni adresar
-d file existuje soubor a je adresar
-z s delka retezce s je nulova
-n s delka retezce s neni nulova
s1=s2 retezec s1 se rovna s2
s1!=s2 retezec s1 se nerovna s2
n1 -eq n2 cisla n1 a n2 jsou si rovna
(podobne pro -ne, -gt, -ge, -lt, -le)
expr args vysledek vyhodnoceni je zapsan na st.vystup
args je vyraz s operatory +,-,*,/,%
a relacnimi operatory <,<=,=,!=,>=,>
true prikaz vracejci pravdu
false nedefinovany prikaz (vraci nepravdu)

exec [args] vymena aktualniho shellu za proces args
 

pouze Bourne shell:
export [names] vyvoz promennych shellu do prostredi
procesu-potomku
trap [arg] [nums] nastaveni reakci shellu na typ signalu
set [-vx] nastaveni ladeni scenare
- ukonceni ladeni
v verbose mode (tisk nactenych radku
pred interpretaci)
x execute (tisk provadenych prikazu)


5.5 Nektera rozsireni C-shellu

C-shell poskytuje nektera vyznamna rozsireni. Zde uvedeme
pouze numericke promenne, udrzovani a pristup k historii prikazu,
mechanismus zamen a rozsireni pro rizeni procesu.

Rozsirene rizeni procesu je zalozeno na pojmu prace (job), kterym
se oznacuje prikazovy radek. Prace se pak muze nachazet ve stavech
provadeni (Running), pozastaveni (Stopped), nestandardniho ukonceni
(Terminated), ukonceni (Done) a selhani (Exit). Pomoci "ctrl-z" je
bezici program pozastaven. Ten lze presunout bud do behu na pozadi
nebo na popredi.

Rozsirujici prikazy:

@var operator expr prirazeni hodnoty vyrazu operator expr
numericke promenne var (vyraz jako v C)
jsou k dispozici testy obdobne prikazu test
-r file existuje soubor dostupny pro cteni
-w file existuje soubor dostupny pro zapis
-f file existuje soubor a neni adresar
-d file existuje soubor a je adresar
-e file soubor existuje
-o file uzivatel je vlastnik file
set history = num nastaveni delky historie prikazu na num
history [-hr] [num] vypis historii v delce n radku
h prepnuti vystupu do souboru
r vypis obracene
source [-h] [file] inicializace historie
h vstup ze souboru bez vykonani
!! opakovani prikazu (n=1)
!-n vykonani prikazu o n zpet v historii
!n vykonani prikazu s cislem n
!chars vykonani prikazu zacinajiciho chars
^str1^str2 zamena str1 za str2 v poslednim retezci
(pro editaci lze pouzit prikazu ed)
alias [name [def]] definice jmena name pro retezec def
(bez def - vypis definice)
unalias name zruseni vyznamu retezce name
jobs vypise seznam praci (jobs)
bg [%n] presun prace na pozadi
fg [%n] presun prace do popredi
%n cislo procesu