Sunteți pe pagina 1din 23

1.

Bourne Again Shell







8.1 Introducere
Bourne Again Shell (bash) ofer o serie de faciliti n plus fa de
shell-ul standard Bourne, att la nivel de interpretor al liniei de comand, ct
i la nivel de limbaj de programare. Printre altele, bash ofer istoric al
comenzilor, alias-uri, auto-completarea comenzilor i a numelor de fiiere,
editarea liniei de comand, etc. Unele dintre aceste faciliti sunt prezente i
n shell-ul standard Bourne, ns proiectul GNU a extins shell-ul pentru a
include un numr de noi faciliti i pentru compatibilitate POSIX.
O dat cu realizarea variantei bash 2.x, au fost adugate att de multe
funcionaliti (unele din Korn shell i C shell), nct shell-ul bash
reprezint un shell complect funcional att la nivel de interpretor ct i la
nivel de limbaj de programare. Shell-ul bash s-a nscut pe 10 ianuarie 1988
sub oblduirea lui Brian Fox i a fost adoptat mai trziu de ctre Chet
Ramey. Prima versiune a fost versiunea bash 0.99, iar cele mai importante
mbuntiri au fost aduse odat cu versiunea 2.0. Toate versiunile sunt
disponibile free sub licen public GNU. Pentru a vedea ce versiune de
bash folosete, un utilizator poate folosi comanda bash --version sau poate
afia valoarea variabilei de mediu BASH_VERSION. Urmtorul exemplu ne
nfieaz o posibil situaie:


$ bash --version
GNU bash, ver si on 2. 04. 11( 1) - r el ease ( i 386- r edhat - l i nux- gnu)
Copyr i ght 1999 Fr ee Sof t war e Foundat i on, I nc.

$ echo $BASH_VERSION
2. 04. 11( 1) - r el ease

BOURNE AGAIN SHELL
8
UNIX
8.2 Iniializare i mediu
n momentul iniializrii, shell-ul bash parcurge o serie de pai.
Primul proces ce se ruleaz n momentul iniializrii este init, cu
identificatorul PID=1. Acest proces iniiaz un proces getty, care deschide
porturile terminalului, oferind un spaiu de manevr pentru standard input
i pentru standard output i standard error. n urma acestui proces va fi
afiat un prompter de login pe ecran. n continuare se execut programul
/bin/login, care cere o parol, cripteaz i verific parola, setnd un mediu
iniial de lucru i pornind shell-ul de login (care n cazul nostru este
/bin/bash).
Dup aceea, procesul (programul) bash caut fiierul de configurare
/etc/profile i execut comenzile din acesta. n continuare, se caut n
directorul home un fiier de configurare iniial denumit .bash_profile. Dup
executarea comenzilor din acest fiier, se va executa o comand din fiierul
ENV al utilizatorului, de regul .bashrc i, n cele din urm, prompter-ul
(semnul $ pentru utilizatorul obinuit sau # pentru root) este afiat pe ecran,
ateptnd introducerea de comenzi.
Dac dorim modificarea shell-ului la linia de comand, putem s
introducem simplu numele shell-ului i s apsm ENTER. De exemplu,
dac folosim la un moment dat shell-ul standard Bourne i dorim s
schimbm n Bourne Again shell, nu avem dect s introducem bash la linia
de comand, urmat de tasta ENTER:


$ ps
PI D TTY TI ME CMD
5549 t t y1 00: 00: 00 sh
5429 t t y1 00: 00: 00 ps

$ bash
bash- 2. 04$

bash-2.04$ ps
PI D TTY TI ME CMD
5449 t t y1 00: 00: 00 sh
5465 t t y1 00: 00: 00 bash
5472 t t y1 00: 00: 00 ps



Explicaii. Iniial, comanda ps (process status) ne arat procesele
aflate n execuie. Se observ c ruleaz shell-ul Bourne (sh). Se introduce
apoi comanda bash la prompter i apare un nou prompter (bash-2.04$).
Bourne again shell
Introducnd din nou comanda ps, se afieaz de data aceasta dou shell-uri
care ruleaz: shell-ul iniial sh i shell-ul bash pornit ulterior.

Fiiere de iniializare
Shell-ul bash are o serie de fiiere de configurare pe care le verific
la pornire. Aceste fiiere de configurare sau iniializare sunt procesate
(rulate) n funcie de mai multi factori (dac shell-ul curent este i shell-ul
de login, dac este un alt shell interactiv diferit dect cel de login, sau un
shell non-interactiv - shell-script). S vedem n continuare care sunt fiierele
de configurare iniial i ordinea n care aceste fiiere sunt procesate.
n momentul login-ului, nainte de apariia prompter-ului shell, este
executat fiierul de configurare global, /etc/profile. Dup aceea, dac
exist, este procesat fiierul .bash_profile din directorul home al
utilizatorului. Acest fiier specific alias-uri i funcii i seteaz variabile de
mediu specifice utilizatorului sau pornete anumite shell-script-uri. Dac
fiierul .bash_profile nu exist, dar exist fiierul .bash_login, atunci acest
fiier va fi procesat, iar dac acesta din urm nu exist, va fi procesat fiierul
.profile (din directorul home al utilizatorului).

8.2.1 Fiierul /etc/profile
Fiierul /etc/profile reprezint un fiier de configurare global a
ntregului sistem. Acest fiier este editat de ctre administratorul sistemului
pentru a executa anumite comenzi atunci cnd se iniializeaz sistemul. El
este executat atunci cnd pornete shell-ul bash. El are acelai efect i n
cazul shell-urilor Korn i Bourne i, de regul, ndeplinete anumite sarcini
precum rularea programului ce administreaz mailul (mail spooler) sau
afiarea unui mesaj iniial, denumit mesajul zilei (message of the day, din
fiierul /etc/motd). n continuare este prezentat un exemplu de fiier
/etc/profile (nu am numerotat liniile goale):

1 #/ et c/ pr of i l e
2 # Syst emwi de envi r onment and st ar t up pr ogr ams
3 # Funct i ons and al i ases go i n / et c/ bashr c

4 PATH=$PATH: / usr / X11R6/ bi n

5 ul i mi t - S - c 1000000 > / dev/ nul l 2>&1
6 i f [ i d - gn = i d - un - a i d - u - gt 14 ] ; t hen
7 umask 002
8 el se
UNIX
9 umask 022
10 f i
11 USER= i d - un
12 LOGNAME=$USER
13 MAI L=/ var / spool / mai l / $USER
14 HOSTNAME=`/ bi n/ host name`
15 HI STSI ZE=1000

16 i f [ - z $I NPUTRC - a ! - f $HOME/ . i nput r c ] ; t hen
17 I NPUTRC=/ et c/ i nput r c
18 f i
19 expor t PATH USER LOGNAME MAI L HOSTNAME HI STSI ZE I NPUTRC

20 f or i i n / et c/ pr of i l e. d/ *. sh ; do
21 i f [ - x $i ] ; t hen
22 . $i
23 f i
24 done
25 unset i

Prezentm n continuare cteva explicaii analiznd fiierul
/etc/profile pe linii:
Liniile 1,2,3 - Comentarii n shell-script;
Linia 4 - Variabilei PATH i se atribuie directoarele unde va cuta
shell-ul comenzile introduse;
Linia 5 - Comanda ulimit stabilete limita maxim a dimensiunii
fiierelor core la 1.000.000 bytes. Fiierele core sunt fiiere create n urma
opririi anormale a programelor i pot ocupa dimensiuni considerabile din
spaiul de pe disc;
Liniile 6-10 - Comanda if care realizeaz urmtoarele: dac numele
grupului este egal cu numele utilizatorului i numrul ID al utilizatorului
este mai mare dect 14, atunci seteaz umask cu valoarea 002. n acest caz,
atunci cnd sunt create directoarele vor avea drepturi de acces 775 iar
fiierele vor avea 664. Altfel, umask va avea valoarea 022, de unde rezult
drepturi 755 pentru directoare i 644 pentru fiiere.
Linia 11 - Variabilei USER i se atribuie valoarea pe care o returneaz
comanda id -un (numele utilizatorului)
Linia 12 - Variabilei LOGNAME i se atribuie valoarea din $USER;
Linia 13 - Variabila MAIL ia valoarea egal cu numele directorului
unde se programul de administare a mail-ului va salva mail-ul;
Linia 14 - Variabila HOSTNAME ia valoarea numelui mainii;
Linia 15 - Variabila HISTSIZE ia valoarea 1000 (numrul de
comenzi stocate n memoria history);
Bourne again shell
Liniile 16-18 - Comanda if care verific dac fiierul cu numele dat
de variabila INPUTRC are dimensiunea diferit de zero i nu exist fiierul
.inputrc din directorul home i n acest caz variabila INPUTRC ia valoarea
/etc/inputrc;
Linia 19 - Variabilele ce apar n aceast linie sunt exportate pentru
a fi disponibile n sub-shell-uri i procese copil;
Linia 20-24 - O comanda for i una if care realizeaz urmtoarele:
pentru fiecare fiier cu extensia .sh din directorul /etc/profile.d, se verific
dac este executabil, iar dac este executabil, se execut fiierul
utilizndu-se comanda dot (.). Fiierele din directorul /etc/profile.d, lang.sh
i mc.sh, seteaz setul de caractere i de fonturi i creaz o funcie denumit
mc (Midnight Commander) care reprezint un browser (asemntor cu
vestitul Norton Commander pentru DOS/Windows) vizual de fiiere. Pentru
pornirea acestuia se scrie mc la linia de comand.
Linia 25 - Variabila i este resetat prin comanda unset, adic tears
din memoria shell-ului.
8.2.2 Fiierul .bash_profile
Dac fiierul .bash_profile este gsit n directorul home al
utilizatorului, atunci este executat imediat dup /etc/profile. Dac
.bash_profile nu exist, atunci shell-ul bash va cuta fiierul .bash_login
sau, dac nici acesta nu exist, fiierul .profile, toate din directorul home.
Doar unul dintre cele trei fiiere menionate anterior va fi executat, iar
cutarea se face n ordinea specificat (bash_profile, .bash_login, .profile).
De asemenea, bash va verifica existena fiierului .bashrc i l va executa
comenzile din acesta dac fiierul exist. Prezentm n continuare un
exemplu de fiier .bash_profile:

1 #. bash_pr of i l e
2 # Get t he al i ases and f unct i ons

3 i f [ - f ~/ . bashr c ] ; t hen
4 . ~/ . bashr c
5 f i

6 PATH=$PATH: $HOME/ bi n
7 BASH_ENV=$HOME/ . bashr c
8 USERNAME=r azvan
9 expor t USERNAME BASH_ENV PATH
10 mesg n

UNIX
Prezentm n continuare cteva explicaii analiznd fiierul
.bash_profile pe linii:
Liniile 1,2 - Comentarii n shell-script;
Liniile 3-5 - Comand if care verific dac fiierul .bashrc se afl n
directorul home i dac exist l ruleaz;
Linia 6 - Variabilei PATH i se adaug o cale ctre subdirectorul bin
din directorul home;
Linia 7 - Variabilei BASH_ENV i se atribuie valoarea specificat
(calea ctre fiierul .bashrc). Fiierul .bashrc conine funcii i alias-uri
definite de utilizator;
Linia 8 - Variabila USERNAME ia valoarea razvan;
Linia 9 -Variabilele specificate sunt exportate pentru a fi valabile n
subshell-uri i procese copil;
Linia 10 - Comanda mesg executat cu opiunea n are ca efect
blocarea mesajelor primite cu comanda write de la ali utilizatori.

8.2.3 Fiierul .bashrc
Fiierul .bashrc este automat executat ori de cte ori un shell bash
pornete, coninnd numai setri valabile pentru shell-ul bash.
Avem n continuare un exemplu de fiier .bashrc:

1 #. bashr c
2 # User speci f i c al i ases and f unct i ons
3 # Sour ce gl obal def i ni t i ons

4 i f [ - f / et c/ bashr c ] ; t hen
5 . / et c/ bashr c
6 f i

7 set - o nocl obber
8 al i as mv= mv - i
9 al i as di r = l s - al
10 f unct i on cd { bui l t i n cd $1; echo $PWD; }

Explicaii:
Liniile 1,2,3 - Comentarii n shell-script;
Liniile 4-6 - Comand if care verific existena fiierului /etc/bashrc
i n acest caz l ruleaz;
Linia 7 - Comanda set apelat cu opiunea noclobber determin
apariia unor mesaje preventive n cazul suprascrierii fiierelor deja
existente;
Bourne again shell
Linia 8 - Se declar un alias pentru comanda mv, astfel nct de
acum ncolo ea va fi apelat automat cu opiunea -i(interactive);
Linia 9 - Se declar un alias pe nume dir, care va efectul apelului
comenzii ls -al;
Linia 10 - Se definete o funcie utilizator. Cnd utilizatorul va
schimba directorul curent se va afia i directorul curent de lucru. Numele
fucniei este cd i conine comanda intern cd (change directory). Comanda
intern builtin precede numele comenzii cd pentru a preveni intrarea n
recursivitate infinit a funciei.
8.2.4 Fiierul .profile
Fiierul .profile este un fiier de configurare definit de utilizator. El
se gsete n directorul home al utilizatorului i este executat imediat dac
shell-ul de login este shell-ul Bourne. n cazul n care shell-ul de login este
bash, fiierul .profile va fi rulat doar dac nici unul din fiierele enumerate
anterior nu exist. Fiierul conine de regul setri ale mediului i ale
terminalului sau alte setri legate de diverse aplicaii, dac acestea sunt
necesare.
Avem n continuare un exemplu de fiier .profile:

1 #. pr of i l e
2 # Fi si er de conf i gur ar e i ni t i al a ce se execut a at unci cand
3 # se ut i l i zeaza shel l - ul sh sau nu exi st a f i si er el e
4 # . bash_pr of i l e sau . bash_l ogi n

5 HOSTNAME=`uname - n`
6 EDI TOR=/ bi n/ vi
7 PATH=/ bi n: / usr / bi n: / usr / ucb: / usr / l ocal : / usr / bi n: .
8 PS1=$HOSTNAME $>
9 expor t TERM HOSTNAME EDI TOR PATH PS1
10 st t y er ase ^h
11 cl ear

Explicaii:
Liniile 1-4 - Comentarii n shell-script;
Linia 5 - Variabila HOSTNAME va lua valoarea returnat de
comanda uname -n;
Linia 6 - Variabila EDITOR ia valoarea /bin/vi. Programe precum
mail i history vor folosi acest editor;
Linia 7 - Variabila PATH este setat;
Linia 8 - Prompter-ului primar i este atribuit valoarea lui
HOSTNAME (numele mainii), urmat de semnul $ i semnul >;
UNIX
Linia 9 - Sunt exportate variabilele specificate, pentru a fi valabile n
subshell-uri i procese copil;
Linia 10 - Comanda stty seteaz caracteristicile terminalului. Tasta
Erase este setat cu valoarea ^h, astfel nct cnd vom apsa tasta
Backspace, litera de dinaintea cursorului va fi tears;
Linia 11 - Comanda clear terge coninutul ecranului.
8.3 Programarea n bash
Scrierea unui shell-script n bash este similar cu operaia n Bourne
Shell. Un shell-script se scrie cu ajutorul unui editor i conine comenzi
UNIX, comentarii i cuvinte cheie de programare shell. Deoarece utilizm
shell-ul bash, prima linie din shell-script va fi:


#!/bin/bash



De asemenea, script-ul trebuie s fie executabil, de aceea vom folosi
comanda chmod pentru a l face executabil. n exemplul urmtor
presupunem c script-ul se numete script01:


$ chmod +x script01
$ ls -lF script01
- r wxr - xr - x 1 r azvan 12 Aug 12: 00 scr i pt 01*



8.3.1 Citirea variabilelor
Citirea variabilelor se face ca i n shell-ul clasic cu comanda read.
Comanda read preia caractere de la tastatura pn cnd se ntlnete un
caracter newline. Caracterul (newline) de sfrit de linie este transformat
ntr-un octet null atunci cnd este citit. Dac nu se specific nici un nume
pentru variabil, linia citit este atribuit unei variabile interne, numit
REPLY. Putem, de asemenea, folosi comanda read pentru a face un program
s se opreasc n momentul n care apsm tasta ENTER. Opiunile
comenzii read sunt prezentate n tabelul 8.1. De exemplu, opiunea -r este
folosit pentru ignorarea perechii backslash/newline, astfel nct caracterul
special backslash este considerat ca parte din linie.

Bourne again shell
Opiunile comenzii read

Tabelul 8.1
Comanda Semnificaie
read raspuns Se citete de la tastatur n variabila raspuns
read r1 r2 Se citete de la tastatur n variabila r1 pn la primul
caracter whitespace sau Enter, apoi n variabila r2
read Se citete n variabila intern REPLY
read -a nume_vector Se citete o list de cuvinte ntr-un vector denumit
nume_vector
read -e Se folosete n shell-ul interactiv
read -p prompter Afieaz un prompter, ateapt input-ul i stocheaz
rezultatul n variabila REPLY
read -r linie Permite introducerea liniilor ce conin un backslash
8.3.2 Operaii aritmetice
Variabilele pot fi declarate ca numere ntregi cu ajutorul comenzii
declare -i. O variabil numar poate fi declarat astfel:


$ declare -i numar



Se pot face operaiile aritmetice uzuale cu variabilele declarate
ntregi, folosind operatorii pentru adunare, scdere, nmulire, mprire i
mprire modulo. Exemple:


$ declare -i numar
$ numar=3+7
$ echo $numar
10
$ numar= 6 + 9
bash: +: command not f ound
( car act er el e whi t espace t r ebui e i ncadr at e de
ghi l i mel e, cor ect est e: numar =6 + 9)
$ numar=4*5
$ echo $numar
20




UNIX
Comanda declare -i fr nici un argument va lista toate variabilele
ntregi definite, precum i valorile lor, ca n exemplul urmtor:


$ declare -i
decl ar e - i r EUI D=0
decl ar e - i r PPI D=846
decl ar e - i r UI D=0
decl ar e - i numar =20
$


Se pot utiliza numere reprezentate n baze de numeraie diferite, de
la baza 2 la baza 36. Formatul general de reprezentare ntr-o anumit baz
este:

variabila=baza#numarul_in_acea_baza



Spre exemplu, dac: nr=2#110, atunci avem numrul 110
reprezentat n baza 2. Se pot declara numere octale (n baza 8) dac valoarea
numeric a acestora este precedat de un 0 (zero). De exemplu, dac avem
comanda: declare -i nr=020, atunci variabila nr are valoarea zecimal 16.

Comanda let
Comanda let este o comand intern bash utilizat pentru a realiza
operaii aritmetice cu ntregi i a testa expresii numerice. Operatorii care
sunt acceptai de comanda let pot fi vizualizai cu ajutorul comenzii: help
let.

Numere reale
Shell-ul bash ofer suport doar pentru operaii cu numere ntregi;
dac avem de fcut calcule cu numere reale, putem folosi utilitarele bc, awk
sau nawk.
Exemple:


$ nr =`echo scal e=2; 12 / 5 | bc`
$ echo $nr
2. 40

$ p=`gawk - v x=2. 2 - v y=3. 3 BEGI N{pr i nt f %. 2f \ n, x*y} `
$ echo $p
7. 26

Bourne again shell
8.3.3 Parametri poziionali i comanda set
Parametrii poziionali sunt aceeai cu cei din Bourne Shell: $0 este
numele script-ului, $1-$9 reprezint valorile parametrilor poziionali iar $*
listeaz toi parametrii poziionali. Dac numrul parametrilor poziionali
era restrns la 9 pentru shell-ul Bourne, n bash putem folosi ci parametri
poziionali dorim. Pentru valori mai mari dect 9, ei vor fi referii astfel:
${10}, ${11}, etc. $* semnific extinderea la un singur argument, de
genul: $1 $2 $3, iar $@ are semnificaia: $1 $2 $3.
Considerm urmtorul exemplu:

#! / bi n/ bash
#Numel e scr i pt - ul ui est e test
echo Numel e scr i pt - ul ui est e $0
echo Pr i mul par amet r u pozi t i onal est e $1
echo Al doi l ea par amet r u pozi t i onal est e $2
echo Al 10- l ea par amet r u pozi t i onal est e ${10}



Apelat astfel:


$. / t est 1 2 3 4 5 6 7 8 9 10 11



vom obine listing-ul:


Numel e scr i pt - ul ui est e . / t est
Pr i mul par amet r u pozi t i onal est e 1
Al doi l ea par amet r u pozi t i onal est e 2
Al 10- l ea par amet r u pozi t i onal est e 10



Comanda set poate fi folosit pentru resetarea parametrilor
poziionali. Dac este apelat fr nici un argument, comanda set va afia
toate variabilele care au fost definite n acel shell, locale sau exportate. n
momentul apelului comenzii cu unul sau mai multe argumente, parametrii
pozitionali definii anterior se pierd (pentru a reveni la valorile iniiale se
poate utiliza comanda set --).




UNIX
Fie exemplul urmtor:


#! / bi n/ bash
#Numel e scr i pt - ul ui est e test2
echo Numel e scr i pt - ul ui est e $0
echo Par amet r i i sunt : $*
echo Al doi l ea par amet r u pozi t i onal est e $2
echo Numar ul par amet r i l or est e $#
ar g_vechi =$*
set i on mar i a cor nel gheor ghe st ef an
echo Par amet r i i sunt acum: $*
set $( dat e)
echo Ast azi est e $3 $2 $6
echo Vechi i par amet r i sunt : $ar g_vechi
set $ar g_vechi
echo $1 $2 $3



n urma execuiei shell-script-ului de mai sus prin apelul: ./test2 1 2
3 se va afia:


Numel e scr i pt - ul ui est e . / test2
Par amet r i i sunt : 1 2 3
Al doi l ea par amet r u pozi t i onal est e 2
Numar ul par amet r i l or est e 3

Par amet r i i sunt acum: i on mar i a cor nel gheor ghe st ef an

Ast azi est e 15 Aug 2004
Vechi i par amet r i sunt : 1 2 3
1 2 3




Variabilele speciale pot fi folosite i n construcii speciale:

#! / bi n/ bash
#Numel e scr i pt - ul ui est e test3
nume=${1: ?necesi t a un ar gument ! }
echo Buna zi ua, $1!



Dac test3 este apelat fr nici un argument, va fi afiat mesajul de
eroare: ./test3: 1: necesita un argument! Dac facem apelul: ./test3 Razvan,
vom obine rezultatul: Buna ziua, Razvan!
Bourne again shell
8.3.4 Construcii condiionale i controlul fluxului
Construciile condiionale ne permit s testm anumite condiii i
apoi s executm anumite comenzi n funcie de rezultatul testrilor.
Comanda if reprezint cea mai simpl construcie condiional utilizat
pentru luarea deciziilor. Ca i shell-ul Bourne, bash utilizeaz valoarea lui
exit-status pentru a vedea care este rezultatul unei comenzi (reamintim c n
cazul n care comanda s-a ncheiat cu succes sau cu valoarea logic true
exit-status-ul este egal cu zero iar n caz contrar exit-status-ul are o valoare
diferit de zero). Valoarea lui exit-status pentru ultima comand este $?.
Pentru a evalua starea de adevr a unei expresii este folosit comanda
intern test, sau se folosesc parantezele ptrate. Considerm n continuare
cteva exemple de utilizare a comenzii test, a parantezelor ptrate, construcia
cu paranteze ptrate duble [[ ]] i cu paranteze duble (( )).

Exemplul 1.

Vomi nt r oduce l a l i ni a de comanda:

$ nume=bar bu
$ gr ep $nume / et c/ passwd > / dev/ nul l
$ echo $?
0 #bar bu a f ost gasi t i n / et c/ passwd

$ t est $nume ! = bar bu
$ echo $?
1 #numel e nu est e di f er i t de barbu

$ [ $nume = bar bu ]
$ echo $?
0 #t est ul est e adevar at de aceast a dat a

$ [ $nume = [ Bb] ar bu ]
$ echo $?
1 #comanda t est nu per mi t e f ol osi r ea met acar act er el or



Pentru a putea utiliza metacaractere n cadrul comenzii test trebuie s
folosim parantezele ptrate duble, ca n exemplul urmtor:


$ [ [ $nume == [ Bb] ar bu ] ]
$ echo $?
0


UNIX
Prin utilizarea parantezelor duble (( )) se pot evalua expresii
numerice. Considerm exemplul urmtor:


$ x=3; y=5
$ ( ( x > y ) )
$ echo $?
1



Rezultatul afiat este 1 deoarece x nu este mai mare dect y (3<5).

Comanda if
Noul format al comenzii if pentru bash este:


if [ [ com_test1 ] ]
then
secventa_comenzi1
else
secventa_comenzi2
fi



sau, pentru testri numerice:


if ( ( com_test1 ) )
then
secventa_comenzi1
else
secventa_comenzi2
fi



Observaie. else este opional.

Comanda exit
Comanda exit este utilizat pentru a termina shell-script-ul i a
reveni la linia de comand. Comenzii exit i se poate da un argument (un
numr ntre 0 i 255) pentru a indica faptul c programul s-a ncheiat cu
succes sau nu. Asemntor cu exit-status-ul, valoarea 0 nseamn ncheierea
cu succes a programului. Argumentul pe care l dm comenzii exit se afl
stocat n variabila $?.

Bourne again shell
Comanda case
Comanda case este utilizat pentru construcii condiionale multiple.
Formatul acesteia este acelai cu formatul shell-ului standard Bourne:


case variabila in
sablon_1)
comenzi
; ;
sablon_2)
comenzi
; ;

*)
comenzi
; ;
esac



Dac nici una dintre valorile sablon_1, sablon_2, etc. nu corespund
valorii variabilei respective, se vor executa n mod implicit comenzile ce
urmeaz dup construcia special *).

8.3.5 Comenzi de ciclare
Comenzile utilizate pentru ciclare sunt: for, while, until, select.
Dintre acestea, primele trei ne sunt familiare din shell-ul Bourne. n shell-ul
bash apare un nou mecanism de ciclare, denumit select, utilizat cu
principalul scop de a crea meniuri.
Comanda select afieaz un meniu cu opiuni numerotate 1, 2, 3 etc.
Afiarea se face n fiierul standard error (pe ecran, implicit). Pe ecran,
cererea de a introduce una dintre opiuni se face prin afiarea prompter-ului
PS3 (al treilea prompter), care implicit are valoarea #?. Dac dorim s
afim un mesaj, va trebui s modificm doar valoarea lui PS3. Dar s
vedem cum funcioneaz comanda select: dup afiarea meniului i a
prompter-ului PS3, se ateapt pentru introducerea unui numr din lista
afiat. Input-ul va fi stocat n variabila special REPLY.
De regul, comanda select se folosete mpreun cu comanda case
pentru a crea un meniu ce permite utilizatorului s fac o selecie dintr-un
meniu i pe baza acelei selecii s execute anumite comenzi. De asemenea,
se pot utiliza variabilele predefinite LINES i COLUMNS pentru a schimba
modul de afiare pe ecran a opiunilor (aceste variabile sunt definite
UNIX
ncepnd cu versiunea 2.0 bash). Pentru a ntrerupe execuia comenzii select
se va folosi fie break (pentru ieirea din ciclul select), fie exit pentru a iei
din program. Formatul general al instruciunii select este:


select variabila in lista
do
comenzi
done




Prezentm n continuare cteva exemple de utilizare a comenzii
select.

Exemplul 1.


#! / bi n/ bash
# Nume shel l - scr i pt : meni u_sel ect
PS3=Sel ect at i opt i unea dor i t a:

sel ect pr og i n uname - n dat e cal who exi t

do
$pr og
done



Execuia programului va duce la afiarea unui meniu:

1) uname - n
2) dat e
3) cal
4) who
5) exi t
Sel ect at i opt i unea dor i t a:


n funcie de opiunea selectat, se va executa comanda respectiv.
Ciclul select va rula fie pn la introducerea opiunii 5 (exit va determina
ieirea din program), fie pn la introducerea combinaiei Ctrl+C.



Bourne again shell
Exemplul 2.


#! / bi n/ bash
# Nume shel l - scr i pt : cul or i
PS3=Al eget i una di nt r e cul or i sau exi t :

select al eger e in al bast r u gal ben ver de exi t

do
case al eger e in
al bast r u)
echo Al bast r ul est e cul oar ea cer ul ui !
br eak; ;
gal ben)
echo Gal benul est e o cul oar e cal da!
br eak; ;
ver de)
echo Ver de est e padur ea!
br eak; ;
*)
echo $REPLY nu est e o opt i une val i da!
echo I ncer cat i di n nou.
; ;
esac
done



Iniial, se va afia meniul:

1) al bast r u
2) gal ben
3) ver de
4) exi t
Al eget i una di nt r e cul or i sau exi t :



n funcie de opiunea aleas se va afia mesajul corespunztor. Dac
se introduce valoarea 4 se va iei din program i orice alt valoare introdus
va afia mesajul n care se precizeaz c nu este o opiune valid i se va
repeta introducerea opiunii.

Rularea instruciunilor de ciclare n background
Instruciunile de ciclare pot fi rulate n background, astfel nct
programul poate continua fr s atepte terminarea instruciunii de ciclare.
UNIX
n exemplul urmtor se trimite un email mai multor utilizatori preluat din
fiierul scrisoare:


#! / bi n/ bash
for nume in r adu andr ei andr a ser ban gabi
do
mai l $nume < scr i soar e
done &



Semnul & (ampersand) de la sfritul instruciunii for determin
execuia ciclului for n background. Programul i va continua execuia pn
la terminarea ciclului for.

Separatorul IFS
Separatorul intern al shell-ului IFS (Internal Field Separator) are
valoare de spaiu, tab sau caracter de linie nou (newline). El este folosit
drept caracter separator n cadrul comenzilor pentru interpretarea semantic
a cuvintelor cheie, precum: for, do, done, etc. Acest separator poate fi
modificat de ctre utilizator dac se dorete utilizarea altui separator ntr-o
list. nainte de a modifica valoarea separatorului, este bine s memorm
vechea valoare a lui IFS n alt variabil, pentru a putea reface starea iniial
a separatorului. Prezentm n continuare un exemplu de modificare a
separatorului IFS.


#! / bi n/ bash
# Exempl u pent r u I FS
nume=Radu: Andr ei : Andr a: Ser ban: Gabi
i f s_vechi =$I FS
IFS=:
for per soana in $nume
do
echo Sal ut $per soana
done

IFS=$i f s_vechi
set Cr i st i Cr i st i na Paul
for pr enume in $*
do
echo Buna zi ua $pr enume
done


Bourne again shell
La nceput, variabila nume are valoarea irului de caractere
Radu:Andrei:Andra:Serban:Gabi, numele fiind separate de cte un caracter
:. Vechea valoare a lui IFS este memorat n variabila ifs_vechi. Deoarece
valoarea lui IFS este un caracter whitespace, trebuie ncadrat ntre
ghilimele. Apoi lui IFS i se atribuie o nou valoare, semnul : care va fi de
acum utilizat pe post de separator. Ca urmare a execuiei shell-script-ului
anterior se va afia:


Sal ut Radu
Sal ut Andr ei
Sal ut Andr a
Sal ut Ser ban
Sal ut Gabi
Buna zi ua Cr i st i
Buna zi ua Cr i st i na
Buna zi ua Paul


8.3.6 Funcii
Funciile au fost introduse n shell-ul Bourne ncepnd cu versiunea
AT&T UNIX SystemVR2 (SVR2) i le-au fost adugate o serie de
mbuntiri n shell-ul Bourne Again. Funciile reprezint asocierea unui
nume pentru o comand sau un grup de comenzi, fiind folosite pentru
modularizarea programelor, fcndu-le astfel mai eficiente. Funciile sunt
executate n contextul shell-ului curent, astfel c nu se creeaz un nou
proces copil ca n cazul rulrii unui program executabil precum cat.
Funciile pot fi scrise n fiiere separate pentru a fi ncrcate n memorie din
shell-script atunci cnd trebuie folosite. n continuare sunt prezentate
regulile de scriere a funciilor n Bourne Again Shell:
1. O funcie trebuie definit nainte de a fi utilizat.
2. Funcia ruleaz n mediul de lucru curent, partajnd variabilele din
shell-script-ul ce o invoc i ofer posibilitatea de transmitere de argumente
prin atribuirea acestora ca parametri poziionali. Variabilele locale pot fi
create n cadrul unei funcii prin utilizarea funciei local.
3. Shell-ul determin dac se folosete un alias, o funcie, o comand
intern sau un program executabil aflat pe hard-disc. Ordinea de cutare
este: alias, funcie, comand intern, program executabil.
4. n momentul n care se utilizeaz comanda exit n cadrul unei
funcii, se produce ieirea din shell-script-ul ce apeleaz funcia. Dac se
UNIX
iese din funcie, ntoarcerea n shell-script se face pe linia urmtoare
apelului funciei.
5. Comanda return n cadrul unei funcii determin returnarea valorii
exit-status a ultimei comenzi executate n cadrul funciei sau valoarea
argumentului specificat.
6. Funciile pot fi exportate n sub-shell-uri folosind comanda intern
export -f.
7. Pentru a lista funciile i definiiile acestora, se folosete comanda
declare -f. ncepnd cu versiunea 2.x. bash, pentru a lista doar numele
funciilor se folosete comanda declare -F.
8. Dac funciile sunt stocate ntr-un fiier separat, acestea pot fi
ncrcate n mediul curent prin comanda source sau comanda dot (.).
9. Se permite declarea funciilor recursive (ce se auto-apeleaz). Nu
exist o limit maxim impus pentru numrul de apeluri recursive.
10. Variabilele, ca i valorile trap sunt globale n cadrul funciilor. Ele
sunt partajate att de ctre shell-script ct i de funciile invocate de acel
shell-script. Dac o valoare trap este definit n cadrul unei funcii, ea este,
de asemenea, partajat de shell-script.

Alte comenzi legate de funcii.
Pentru a reseta o funcie se folosete comanda unset. Formatul
general al acestei comenzi este:


unset -f nume_functie


Pentru a exporta o funcie ntr-un sub-shell se folosete comanda
export. Formatul general al acestei comenzi este:


export -f nume_functie



n cadrul unei funcii, argumentele pot fi transmise funciilor prin
intermediul parametrilor poziionali. Parametrii poziionali sunt privai n
cadrul funciilor, astfel nct argumentele unei funcii nu vor afecta
parametrii poziionali utilizai n afara acesteia. Pentru a crea variabile
locale (care nu vor mai fi valabile la ieirea din funcie) pentru o funcie
anume putem folosi comanda intern local.
Comanda return poate fi utilizat pentru a termina execuia funciei
i a preda controlul script-ului apelant. Valoarea returnat de o funcie este
egal cu valoarea exit-status returnat de ultima comand executat
Bourne again shell
n cadrul funciei, cu excepia cazului n care se specific un anumit
argument prin intermediul comenzii return. n momentul n care se specific
o valoare prin comanda return, aceast valoare este stocat n variabila ? i
poate lua valori ntregi cuprinse ntre 0 i 255. Datorit acestei limitri, se
poate utiliza substituirea comenzii pentru a captura valoarea returnat de o
funcie. n acest sens, se poate scrie toat funcia ntre paranteze precedate
de semnul $ sau ntre apostrofurile inverse (``) pentru a captura i atribui
valoarea returnat de ctre funcie unei variabile, ca i n cazul obinerii
rezultatului unei comenzi UNIX.
Prezentm n continuare cteva exemple de utilizare a funciilor.

Exemplul 1.


#! / bi n/ bash
# Nume shel l - scr i pt : ver i f i c_f unct i e

f unct i on UTI { echo Er oar e: $* 2>&1; exi t 1; }

i f ( ( $# ! = 2 ) )
t hen
UTI $0: necesi t a doua ar gument e
f i
i f [ [ ! ( - r $1 && - w $1 ) ] ]
t hen
UTI $1: f ar a dr ept ur i de ci t i r e si scr i er e
f i
echo Ar gument el e sunt : $*
. . . # comenzi



Explicaii.
n exemplul anterior se definete o funcie UTI ce este utilizat
pentru a afia un mesaj de eroare pe ecran (fiierul standard de eroare).
Argumentele funciei constau n orice ir de caractere trimise odat cu
apelul funciei. Argumentele sunt stocate n $*, variabila special ce
stocheaz toi parametrii poziionali. n cadrul unei funcii, parametrii
poziionali sunt considerai locali i nu au efect asupra parametrilor utilizai
n afara funciei. n cadrul script-ului se verific dac numrul parametrilor
poziionali este 2 i n caz contrar se afieaz mesajul de eroare
corespunztor. n momentul apelrii funciei UTI, irul $0: necesita doua
argumente este transmis funciei i memorat n variabila $* iar comanda
echo va afia mesajul de eroare i apoi se va returna valoarea de ieire 1,
ceea ce indic faptul c ceva nu a fost n regul. n continuarea programului,
UNIX
se verific dac primul argument este un fiier care poate fi citit i
modificat, iar funcia UTI va fi apelat cu argumentul $1: fara drepturi de
citire si scriere. Argumentele ce provin de la linia de comand sunt stocate
din nou n $*, fr a avea efect pentru valoarea $* din cadrul funciei.

Exemplul 2.


#! / bi n/ bash
# Nume shel l - scr i pt : i ncr ement ar e

I NC ( ) {
l ocal suma;
l et suma=$1 + 1
r et ur n $suma
}
echo - n Suma est e:
I NC 5
echo $?
echo $suma # var i abi l a suma nu est e cunoscut a i n
#af ar a f unct i ei



Explicaii.
n exemplul anterior se definete o funcie INC. n cadrul acestei
funcii se declar variabila local suma, care nu este cunoscut n afara
funciei. n momentul apelului funciei, valoarea primului argument, $1 va fi
incrementat cu 1 iar rezultatul va fi atribuit variabilei suma. Comanda
intern return va atribui variabilei $? valoarea din variabila suma, apoi irul
este afiat pe ecran. Funcia INC este apelat cu argumentul 5, iar
exit-status-ul ei va fi stocat n variabila $?. Pentru ultima linie din program
nu se va afia nimic, deoarece variabila suma a fost declarat doar n
interiorul funciei (cu ajutorul comenzii interne local) i valoarea acestei
variabile nu este cunoscut n afara funciei.









Bourne again shell
Exemplul 3.


#! / bi n/ bash
# Nume shel l - scr i pt : cub

f unct i on CUB {
l ocal r ez;
l et r ez=$1 * $1 * $1
echo Numar ul ce va f i r i di cat l a cub est e $1
echo Rezul t at ul est e $r ez
}
echo - n I nt r oducet i numar ul pent r u r i di car e l a cub:
r ead numar
r ezul t at =$( CUB $numar )
echo - n $r ezul t at



Explicaii.
n exemplul anterior se definete o funcie CUB. n cadrul acestei
funcii se declar variabila local rez, care va stoca rezultatul. n cadrul
script-ului se citete valoarea care va fi ridicat la cub n variabila numar,
apoi se atribuie variabilei rezultat valoarea ntoars de funcie prin
intermediul substituirii comenzii (construcia cu numele funciei ntre
paranteze precedate de semnul $). Prin comanda echo de pe ultima linie a
shell-script-ului se afieaz rezultatul.

Observaie. Ca i n Bourne Shell, funciile se ncarc n memorie cu
ajutorul comenzii dot (.). n Bourne Again Shell exist ns i comanda
source, care se apeleaz astfel:


$ source fisier_functii



unde fisier_functii este fiierul ce conine funciile ce vor fi utilizate.

S-ar putea să vă placă și