Hatodik lecke

"Az igazi Unix buherátor művész. Mint minden művész, ő is önön lényegét alkotja újjá az anyagban - ami jelen esetben a shell, annak változói és környezete."
(Csáky István)
Verzió: 1.0

Bővebben az átirányításról

A harmadik leckében volt szó az átirányításról. Ebben a leckében pár hasznos példát mutatunk az átirányítás "haladóbb" alkalmazására. Bonyolultabb átirányításokhoz az sh (vagy sh típusú shell) alkalmazása javasolt, ezért a példák is az sh alkalmazásával készültek. (Akinek csh az alapértelmezés, az a Bourne shellt az sh beírásával indíthatja!)*

Mit csináljunk például akkor, ha az stderr-t (a hibacsatornát) szeretnénk egy fájlba irányítani? Ehhez először is tudnunk kell, hogy az alapértelmezés szerinti csatornáknak (stdin, stdout, stderr), egy-egy szám a megfelelőjük; az stdin-é a 0, az stdout-é az 1 és az stderr-é a 2. Ezeknek a számoknak a használatával lehet bonyolultabb átirányítási feladatok megoldására kényszeríteni a Unixot. Például, ha a cat parancs hibajelzéseit át szeretnénk irányítani egy caterr nevű fájlba, a következőket kell tennünk:

sindbad> sh 
sindbad% cat level 2>caterr 
sindbad% cat caterr 
cat: cannot open level 
sindbad% 
Mivel a level nevű fájl nem létezik, a cat program hibajelzést ad, amit mi a caterr nevű fájlba irányítottunk át.

Másik nagyon gyakran előforduló probléma, hogy egy program kimenetét és hibáit szeretnénk egy fájlban látni, de mivel a Unix a hibákat a képernyőre írja ki - abban az esetben is, ha a program a háttérben fut - átirányításra van szükség.

sindbad> sh 
sindbad% program 1>errors 2>&1 
sindbad% 
A & jel azt jelenti, hogy nem egy fájlba irányítunk át, hanem egy másik csatornába, jelen esetben az stdout-ra.

A shell változók és a környezet

A shell részben programozási nyelv is, ezért tartalmaz változókat.

Figyelem! Az sh-ban (sh, ksh, bash, zsh) és a csh-ban (csh, tcsh) másként kell értéket adni a változóknak!

Az sh típusú shellek az "=" jelet használják:

sindbad% a="hello sh" 
míg a csh típusúakban a set parnaccsal kell értéket adni a változóknak:
woland> set a="hello csh" 

A kiíratást mindkét shell esetében az echo parancs végzi, a változó neve előtt pedig egy $ jelnek kell szerepelnie:

sindbad% echo $a 
hello sh 
sindbad% 
Ezek a shell belső változói - tehát csak az aktuális shellben ismertek, lokálisak. A shell lehetővé teszi a futtatandó programok környezetének (environment) beállítását is. A környezet azon változók csoportja, melyek minden programból elérhetőek, globálisak. A környezet beállításának szempontjából is különbözik az sh és a csh. A környezet beállítása sh-ban:

Állítsunk be valami hasznosat. A PAGER környezeti változó, amelyet például a man parancs használ megjelenítőprogramként, éppen megfelel erre a célra.

sindbad% PAGER="cat" 
sindbad% export PAGER 

Ennek kicsit kellemetlen az eredménye, mivel ha man-t kérünk, csak elrohan a szöveg a szemünk előtt, de példának megteszi! Azonban, ha képernyőnként szeretnénk látni, akkor állítsuk be a more-t nézegető programnak:

sindbad% PAGER="more" 
sindbad% export PAGER 
A környezeti változók beállításának csh-beli megfelője a setenv parancs. A fenti példa csh-s megfelelője tehát:
woland> setenv PAGER cat 
és
woland> setenv PAGER more 
Amennyiben egy lokális vagy környezeti változóra nincs szükségünk, eltüntethetjük őket, mintha sosem lettek volna. Sh-ban unset változónév, csh-ban a lokális változókra unset változónév, a globálisokra pedig unsetenv változónév. Azt hogy milyen változók vannak beállítva úgy tudhatjuk meg, hogy a set és a setenv parancsok után nem írunk változónevet.

A PATH környezeti változó

Kiemelten kezeli a shell a PATH (csh-ban path) nevű változót, ugyanis ez a változó jelzi a shell számára, hogy hol kell keresnie a futtatandó programot. Például:
sindbad% echo $PATH 
/bin:/usr/bin:/usr/local/bin:. 
sindbad% 
A fenti példa az sh-t mutatja, mindez csh-ban így néz ki:
woland> echo $path 
/bin /usr/bin /usr/local/bin . 
woland> 
A különbség világosan látható. Tehát a shell először megnézi, hogy a futtatandó program a /bin-ben, a /usr/bin-ben, a /usr/local/bin-ben végül pedig az aktuális könyvtárban (a "." ezt jelzi) található-e?

Automatikus indítású shell scriptek

Minden shell képes arra, hogy indulásakor egy adott nevű shell scriptet elindítson, így a felhasználóknak lehetőségük van arra, hogy környezetüket személyiségükhöz igazítsák.

Ez a program az sh-nál a munkakönyvtárban (home dir) lévő ".profile", csh esetében pedig a bejelentkezés esetén a ".login" és minden más csh indításnál a munkakönyvtárban lévő ".cshrc". Ki-ki ebbe teheti az általa kedvelt változó és környezetbeállításokat.*

Egy minta .cshrc fájl

Lássuk miket lehet beállítani egy .cshrc fájlban.
woland> cat .cshrc 
set history=100 
alias h	history 
alias ls	ls -F 
alias ll	'ls -l | more' 
set prompt="`hostname` > " 
woland> 
Lássuk mit csinál ez a kis "program". A set history arra szolgál, hogy a begépelt parancsainkat a rendszer megőrizze, hogy ha már egyszer begépeltünk valamit, ne kelljen ismét begépelni. A 100-as szám azt jelzi, hogy 100 parancsot őrizzen meg.

A h parancs most a history parancs ekvivalense - a history parancs az eddig begépelt utasításokat listázza ki.

A következő sorban az ls az ls -F-nek lesz az ekvivalense. Ezután minden ls parancs automatikusan ls -F lesz. (Nézzük meg a man-ban, hogy mit csinál az ls F kapcsolója).

Az ezutáni sor még érdekesebb, mivel arra példa, hogy egy utasítássorozatnak legyen egy rövid neve. Tehát egy bő lista kimenetét átadjuk a more nézegető programnak, hogy oldalanként lássuk a kimenetet.

Ezután a prompt beállítására láthatunk példát. A gép először lefuttatja a hostname programot, ami kiírja a gép nevét és azt berakja a promptba. A ` (visszafelé mutató egyes idézőjel) jelentése, hogy a program futásának eredményét helyettesítse be a hostname szó helyett.*

Az alias parancs arra szolgál, hogy egy hosszabb utasítássorozatot egy parancs begépelésével indíthassunk vagy hosszú parancsnév esetén a program nevét Unixabbra alakítsuk (minél rövidebb annál jobb). A jelenleg definiált aliasokat a paraméter nélkül hívott alias parancs mutatja meg; egy-egy alias-t pedig az unalias paranccsal tudunk megszüntetni.*

Terminál beállítások

Az egyik leghasznosabb dolog, amit az automatikusan elinduló .cshrc vagy .profile fájllal csinálhatunk, a terminálunk beállítása. Bizonyára mindenki találkozott már azzal a kellemetlen jelenséggel, hogy egy terminálról való bejelentkezés után bizonyos billentyűk váratlan dolgokat művelnek. Ilyen például, hogy a visszatörlés (backspace) az utolsó karakter törlése helyett ^?-t ír ki, vagy törli a teljes sort.

A jelenség magyarázata a terminálok működésében keresendő. Amikor leütünk egy billentyűt, a terminálunk elküld egy kódot a számítógépnek. A Unix értelmezi ezt a kódot, és csinál valamit. Baj csak akkor van, ha a Unixunk rosszul értelmezi az általunk küldött kódokat: így keletkeznek a ^H, ^?, jelek és egyéb mellékhatások.

A terminál beállításait az stty paranccsal listázhatjuk ki. A -a kapcsolóval teljes listát kapunk. (Némely Unixnál ezt a kapcsolót másképp hívják - ilyenkor nézzük meg a manualt!)

zeus% stty -a
speed 9600 baud; line = 1;  
intr = ^C; quit = ^\; erase = DEL; kill = ^U; eof = ^D; eol <undef>; swtch = ^Z 
lnext = ^V; werase = ^W; rprnt = ^R; flush = ^O; stop = ^S; start = ^Q 
-parenb -parodd cs8 -cstopb hupcl cread clocal -loblk -tostop  
-ignbrk brkint ignpar -parmrk -inpck istrip -inlcr -igncr icrnl -iuclc  
ixon -ixany -ixoff  
isig icanon -xcase echo echoe echok -echonl -noflsh  
opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3  
zeus% 
A listán funkciókat látunk (intr, quit, erase...) és az őket aktiváló kódokat (^C, ^\, DEL, ...) Ezek közül a legfontosabb az erase. Ez a funkció törli a kurzortól balra álló karaktert. A fenti példán értéke DEL, azaz a DEL billenyű leütésével lehet végrehajtani.

Ha a terminálunkon lévő DEL feliratú gomb nem a megfelelő kódot küldi, akkor nem a kívánt művelet történik. Ezt úgy küszöbölhetjük ki, hogy az erase funkcióra egy másik kódot definiálunk, például a ^H-t. Ezután a <Ctrl-h>-val lehet majd törölni. Másik (kényelmesebb megoldás, ha az erase funkciót ahhoz a kódhoz rendeljük hozzá, amit a DEL feliratú billentyűnk generál. Az erase funkció átdefiniálása ugyancsak az stty paranccsal történik. Tételezzük fel, hogy a backspace billentyűvel szeretnénk törölni, de ha leütjük ezt a billentyűt, akkor ^? jelenik meg a képernyőn. Gépeljük be, hogy:

stty erase "^?" 
Ezután nyugodtan törölhetünk a backspace billentyűvel is. A többi funkció beállítása hasonlóan működik.

További fontos funkciók:

intr
Megszakítja a futó programot. Általában a ^C-vel lehet végrehajtani.

kill
Kitörli a parancssorba eddig begépelt szöveget (ha még nem ütöttük le az Entert.)

eof
Ez a jól ismert fájlvége jel. Ez szine mindenhol <Ctrl-d>.

stop
Felfüggeszti a képernyőre írást.

start
Folytatja a stoppal befagyasztott képernyőre írást.

swtch
Az aktuális program futásának felfüggesztése (lásd harmadik lecke).

Természetesen nagyon fáradságos, ha minden paraméter legkedvezőbb beállítását nekünk kell kikísérletezni. Ezért definiáltak néhány beállítás-készletet, amelyekre a nevükkel lehet hivatkozni. Ilyen például a dec terminál; gyakran segít, ha kiadjuk az stty dec parancsot.

Feladatok

  1. Listázzuk ki a .profile vagy .cshrc fájlunk tartalmát! Valószínűleg találunk benne néhány alias utasítást, amelyeket a rendszeradminisztrátor helyezett el számunkra. Próbáljuk meg kitalálni, hogy melyik mire való!*

  2. Találjuk ki, hogy mit csinálnak az alábbi alias definiciók!
    A "\!*" jel a paraméter helyettesítést jelenti, azaz mindent amit a cd után beírunk. Próbáljuk ki, és ha tetszik, építsük be a .cshrc vagy .profile fájlunkba!
    woland> cat .cshrc 
    alias setprompt	'set prompt="$cwd > " 
    alias cd "chdir \!*; setprompt" 
    setprompt 
    woland> 
    
    Az sh-ban nincsenek aliasok, helyettesítésük függvényekkel lehetséges. A fenti példa sh-ban:
    sindbad% cat .profile 
    h()	{history} 
    ls()	{ls -F} 
    ll()	{ls -l | more} 
    sindbad% 
    

*************************************************************************
*=                                                                     =*
*=                           SZERZOI JOGOK                             =*
*=                                                                     =*
*=   Ez  a dokumentum a Unix  operacios  rendszer  es a szamitogepes   =*
*=   halozatok elterjedeset  kivanja  elosegiteni, ezert dijmentesen   =*
*=   terjesztheto.  Nem szabad azonban a terjesztes soran a szoveget   =*
*=   megvaltoztatni,  barmilyen  modon  megcsonkitani  es a  szerzoi   =*
*=   jogokra vonatkozo megjegyzest eltavolitani!  Sem  a dokumentum,   =*
*=   sem annak barmely resze nem hasznalhato fel segedanyagkent vagy   =*
*=   tankonyvkent profitorientalt intezmenyekben vagy tanfolyamokon,   =*
*=   a szerzok elozetes irasbeli engedelye nelkul!                     =*
*=                                                                     =*
*=   (C) Csaky Istvan es Mork Peter         Miskolc, 1994. januar 19   =*
*=                                                                     =*
*************************************************************************