Home - Rasfoiesc.com
Educatie Sanatate Inginerie Business Familie Hobby Legal
Doar rabdarea si perseverenta in invatare aduce rezultate bune.stiinta, numere naturale, teoreme, multimi, calcule, ecuatii, sisteme




Biologie Chimie Didactica Fizica Geografie Informatica
Istorie Literatura Matematica Psihologie

Linux


Index » educatie » » informatica » Linux
Proceduri shell (Shell scripts)


Proceduri shell (Shell scripts)




Proceduri shell (Shell scripts).

Shell-ul nu este doar un interpretor simplu de comenzi ci are totodata si un limbaj de programare in care pot fi scrise noi comenzi, prin folosirea comenzilor existente. Un fisier de comenzi (shell script) este un fisier care contine o secventa de comenzi ale shell-ului.

Crearea si executarea unui fisier de comenzi.

Un script este creat prin crearea unui fisier continand secventa dorita de comenzi. El poate fi executat in doua moduri :

Specificandu-l explicit ca si fisier de intrare pentru shell :




$ sh myscript

sau

$ sh < myscript

Dand numele fisierului de comenzi exact ca orice alta comanda, in linia de comanda a shell-ului :

$ myscript

Pentru ca cea de a doua metoda sa functioneze trebuie ca utilizatorul sa aiba dreptul de executie asupra respectivului fisier. Aceasta se poate realiza prin comanda :

$ chmod u+x myscript

Cand shell-ul incearca sa execute o comanda el mai intai verifica daca utilizatorul are dreptul de a executa acea comanda, iar daca da atunci verifica daca comanda este un program executabil sau un script (folosind primii doi bytes din fisier, acesti doi bytes constituind ceea ce se numeste numar magic - magic number).

Variabile si parametri care pot fi prevazuti in pseudo-programe shell.

Shell-ul permite folosirea variabilelor pentru a manipula valori numerice si siruri. O variabila poate fi creata simplu atribuindu-i o valoare, iar daca se foloseste o variabila inainte de a i se atribui o valoare, atunci va avea ca si valoare sirul vid. Atribuirile pot aparea in felul urmator :

$ NAME=chris

$ BIRTHDAY='December 1st'

In exemplul de mai sus s-au definit doua variabile NAME si BIRTHDAY la care li s-au atribuit sirurile 'chris' si respectiv 'December 1st'. Pentru a folosi valoarea unei variabile intr-o linie de comana, numele variabilei va fi precedata de caracterul '$'. Avand cele doua atribuiri de mai sus urmatoarele doua comenzi sunt echivalente :

$ echo $NAME was born on $BIRTHDAY

chris was born on December 1st

$ echo chris was born on December 1st

chris was born on December 1st

Shell-ul are mai multe variabile speciale, care sunt setate automat si au un rol special :

HOME - indica calea catre directorul utilizatorului. Acesta este directorul care devine directorul curent cand se da comanda cd fara parametri.

PATH - contine o serie de directoare separate prin caracterul ':', acestea sunt locurile unde shell-ul va cauta dupa fisierele pentru comenzile care se doresc a fi executate.

PS1 - contine promptul shell-ului, de obicei setat initial la '$ '

PS2 - este promptul de continuare, daca comanda se extinde pe mai mult de o singura linie, initial '> '.

- este identificatorul de proces al shell-ului curent (nu se poate schimba !).

- este identificatorul de proces al comenzii lansate cel mai recent in background.

- este starea de iesire a comenzii precedente.

- sunt argumentele cu care a fost apelat script-ul. De exemplu :

$ myscript chris staff 'December 1st'

'$1' va fi inlocuit prin 'chris', '$2' prin 'staff' si '$3' prin 'December 1st'.

- este numele prin care a fost apelat script-ul. In exemplul precedent '$0' ar fi inlocuit prin 'myscript'.

- este inlocuit printr-o lista a tuturor argumentelor scriptului. Din exemplul precedent '$*' ar fi inlocuit prin 'chris staff December 1st'.

- reprezinta numarul de argumente din linia de comanda. In exemplul precedent este 3.

O alta modalitate de a seta o variabila shell este utilizand comanda shell read care citeste o linie de la intrarea standard si o asigneaza unei variabile.

Ex:

echo 'What program do you want to compile ?'

read NAME

cc $NAME

Intrarea si iesirea standard.

Intrarea si iesirea standard al unui script sunt ca si la celelalte comenzi mostenite de la shell-ul care l-a lansat. Deci si pentru scripturi functioneaza aceleasi redirectari ca si la comenzile obisnuite. In plus in scripturi se pot face redirectari ale comenzilor din script.

Structuri de control in proceduri shell.

Ca si majoritatea limbajelor de programare, shell-ul include constructii pentru cicluri si executii conditionate ale comenzilor. Constructiile corespunzatoare ciclurilor sunt : for, while si until. Constructiile conditionale sunt : if si case.

Constructia if foloseste starea de iesire (exit state) a unei comenzi. Fiecare comanda care se executa intoarce o valoare numerica cand se termina. Conventia este ca o valoare de iesire de 0 corespunde unei terminari normale, pe cand o valoare diferita de 0 corespunde unei terminari anormale.

Formatul instructiunii if este :

if commanda

then

secventa de comenzi

elif comanda

then

secventa de comenzi

else

secventa de comenzi

fi

Daca prima comanda se termina cu starea 0, atunci va fi executata prima secventa de comenzi, iar restul nu va fi executat. Altfel comenda din partea de elif va fi executata si daca starea de iesire a acelei comenzi este 0 secventa de comenzi corespunzatoare va fi executata. Partea de else va fi executata doar daca toate testele anterioare intorc valori diferite de 0. Partile elif si else sunt optionale.

Exemplu :

Urmatorul script va verifica aparitia valorii din variabila NAME intr+un fisier numit namelist si va afisa mesaje diferite depinzand de faptul daca s-a gasit sau nu acea valoare.



if grep -s $NAME namelist

then

echo $NAME is OK

else

echo I have never heard of $NAME

fi

Urmatorul script exemplifica folosirea programului test, care poate fi folosit pentru a testa existenta unui fisier, daca acesta poate fi citit sau scris, pentru verificarea egalitatii a doua siruri sau daca un numar este mai mare, egal sau mai mic decat un alt numar s.a.m.d. Pentru optiunile permise de programul test se poate consulta manualul online. Acest script va adauga continutul fisierului messagefile la sfarsitul fisierului summarzfile si goleste fisierul messagefile

if test -r messagefile

then

if test -w summaryfile -a -w messagefile

then

cat messagefile >> summaryfile

cp /dev/null messagefile

else

echo Cannot write to sumary or message file

fi

else

echo Cannot read messagefile

fi

Constructia case corespunde unei instructiuni de selectie multipla, asemanatoare cu switch din C sau case din Pascal. Formatul acesteia este :

case word in

pattern11 | pattern12 | )

secventa de comenzi1

;;

pattern21 | pattern22 | )

secventa de comenzi2

esac

Valoarea specificata prin word este testata pe rand cu fiecare tipar si la prima potrivire se va executa secventa de comenzi corespunzatoare. Ca si observatie fiecare secventa de comenzi este terminata prin doua caractere punct si virgula (';'). Tiparele corespund tiparelor utilizate de shell pentru nume de fisiere. Se pot specifica tipare alternative pentru aceeasi secventa de comenzi, acestea se vor separa prin caracterul bara verticala ('|').

Exemplu :

Urmatorul exemplu demonstreaza folosirea tiparului '*' ca si tipar implicit daca nici un alt tipar nu se potriveste, precum si doua moduri diferite pentru a alege o optiune indiferent de litere mari sau mici.

case $OPTION in

-p|-P)

print $FILE

;;

-[nN])

nroff $FILE

;;

*)

echo Unknown option $OPTION

;;

esac

Cicluri pot fi scrise utilizand un cilcu while (sau until) care executa repetat o comanda, testeaza starea de iesire a acesteia si daca este 0 (diferit de 0 pentru until) executa o secventa de comenzi corespunzatoare. Cand starea de iesire devine diferita de 0 (0 pentru until) shell+ul trece la intructiunea de dupa cilcu. Formatul celor doua este :

while comanda

do

secventa de comenzi

done

until comanda

do

secventa de comenzi

done

Exemplu :

REPLAY=yes

while test $REPLAY = yes

do

echo 'Here we go again !'

echo 'Do you want to go round the loop another time ?'

read REPLY

done

Ultima constructie folosita pentru cicluri este for care are urmatorul format :

for nume_de_variabila in lista_de_cuvinte

do

secventa de comenzi

done

Secventa de comenzi este executata odata pentru fiecare cuvant din lista_de_cuvinte. Variabila va lua valori succesive din lista de cuvinte. Lista de cuvinte poate fi generata folosind tipare ca si acelea folosite pentru nume de fisiere. Deasemenea lista de variabile poate lipsi, caz in care ca si lista de variabile va fi considerata lista de argumente cu care a fost lansat shell-ul (adica $*).



Exemplu :

for file in *

do

echo $file

mv $file $file.old

done

for argument

do

cat $argument

done

Comentarii.

In script-uri se pot include si comentarii, prin folosirea comenzii ':', aceasta este o comanda care nu face nimic, astfel incat argumentele sale pot fi folosite ca si comentarii. Dar argumentele acestei comenzi sunt prelucrate la fel ca si argumentele altor comenzi, deci trebuie sa satisfaca aceeasi sintaxa ca si cele pentru comenzile normale. O forma sigura pentru comentariu este ca acesta sa fie pus intre apostroafe.

Exemplu :

Urmatorul exemplu pe langa exemplificarea comentariilor, introduce si o noua comanda exit care determina terminarea executiei scriptului.

: 'are there too few arguments ?'

if test $# -lt 3

then

echo Not enough arguments

exit 1

: ' or too many ?'

elif test $# -gt 5

then

echo Too many arguments

exit 2

fi

Substitutia comenzilor.

Este posibila constructia unei parti a unei comenzi prin executarea unei alte comenzi. Daca o comanda care este incadrata intre caractere '`' (accente grave), este incorporata intr-o linie de comanda, atunci iesirea sa standard, cu trecerile la linie noua inlocuite prin spatii, va fi introdusa in locul acesteia in linia de comanda. Comanda din interiorul accentelor grave poate fi orice comanda valida, chiar si un canal (pipeline).

Exemplu :

Urmatoarea comanda va afisa o lista de fisiere din directorul curent in ordine inversa.

$ echo `ls | sort -r`

Ordinea evenimentelor.

Pentru a intelege script-uri complexe este necesar sa stim in ce ordine se fac substitutiile de catre shell.

Se fac substitutiile de parametri si variabiles toate aparitiile lui '$' urmat de un nume, cifra sau una dintre numele de variabile speciale ca si '*' sunt substituite, in afara situatiei in care caracterul '$' se gaseste inconjurat de apostroafe sau este precedat de ''.

Se fac substitutiile comenzilor, in afara faptului cand accentul grav apare inconjurat de apostroafe sau precedat de ''. Deci ambele substitutii mentionate pana acum au loc si in interiorul unor siruri inconjurate cu ghilimele, acestea sunt diferentele dintre siruri inconjurate de apostroafe (single quotation) si siruri inconjurate de ghilimele (double quotation).

Se fac substitutiile numelor de fisiere ('*', '?' si '[]'), in afara cayului cand aceste caractere speciale sunt inconjurate cu apostroafe sau ghilimele sau precedate de ''.

Optiunile shell-ului.

Cand shell-ul este lansat explicit prin comanda sh este posibila transmiterea unor optiuni pentru controlarea executiei acesteia. Cele mai folositoare optiuni sunt S

-e Determina terminarea executiei imediat ce o comanda din script da gres.

-v Determina tiparirea fiecarei linii pe masura ce este citita.

-x Tipareste comenzile pe masura ce ele sunt executate.

Optiunile pot fi setate si din interiorul unui script folosind comanda set. De exemplu :

set -vx

va determina tiparirea fiecarei linii si tiparirea comenzilor pe masura ce ele sunt executate.

Redirectarea intreruperilor.

In unele script-uri poate fi utila posibilitatea terminarii 'curate', in cazul in care se intampla ceva neprevazut, ca de exemplu apasarea de catre utilizator a tastei de intrerupere sau de terminare. Comanda de redirecatre are forma :

trap actiune lista_de_evenimente

lista_de_evenimente este o lista de intregi, corespunzatoare semnalelor UNIX. actiune este comanda care sa fie executata cand apare un semnal din lista de semnale. Daca action este un sir gol atunci evenimentele corespunzatoare sunt ignorate.

Cele mai folositoare semnale sunt :

0 Iesire din shell.

2 Intrerupere de la terminal.

3 Semnal de terminare de la terminal.

15 S-a receptionat semnalul Kill.

Exemplu :

Urmatorul exemplu demonstreaza folosirea redirectarii intreruperilor in cazul in care la terminarea unui script este necesara stergerea unui fisier temporar.

trap 'echo Interrupteds exit' 2 3

trap 'rm -tmp-tmpfile' 0

Ambianta sau mediul de lucru.

In UNIX toate procesele poseda un mediu de lucru (ENVIRONEMENT), care este o colectie de nume care au asociate valori sir de caractere. Cand shell-ul este pornit el isi incarca ambianta initiala, care consta din variabilele shell-ului si valorile initiale ale acestora. Mai departe el transmite acest mediu, aceasta ambianta, catre toate comenzile pe care le executa. De obicei noile variabile create intr-un shell nu sunt incluse implicit in ambianta. Daca se doreste includerea de noi variabile in ambianta aceasta se face explicit prin comanda export.

$ export NAME BIRTHDAY

Comanda de mai sus adauga variabilele NAME si BIRTHDAY la ambianta curenta a shell-ului si care va fi mostenita de orice comanda pe care acesta o va executa in continuare. Schimbarea ambiantei unui shell sau a unui program nu va avea efect asupra ambiantei shell-ului sau programului care a lansat in executie acel shell sau program.



Exista insa un mod de a altera ambianta unui shell dintr-un sub-program si anume prin folsirea comenzii eval. Aceasta comanda pur si simplu evalueaza argumentele sale ca si cum ele ar fi constituit o linie de comanda a shell-ului. Astfel daca un program name scrie, de exemplu, 'NAME=chris' la iesirea standard, atunci comanda :

$ eval `name`

este echivalenta cu :

$ NAME=chris

avand efectul setarii variabilei de mediu NAME. Un alt mod este de a determina executia unui script chiar de catre shell-ul curent si nu de catre un sub-shell. Acest lucru se poate face folosind comanda '.'.

$ . setup

va avea efectul includerii in fluxul de intrare a fisierului setup.

In anumite cazuri se poate ca sa se doreasca ca valorile anumitor variabile sa nu poata fi modificate. Acest lucru poate fi facut prin comanda readonly :

readonly NAME BIRTHDAY

aceasta comanda va determina raportarea unei erori daca se va incerca modificarea valorii acestor variabile.

Lansarea shell-ului din login.

Cand se intra pentru prima oara in lucru in UNIX, sistemul porneste un shell. Acest shell inainte de a citi de la terminal, va cauta in directorul de login dupa un fisier numit .profile si daca acesta exista va citi si executa comenzile din el. Acest lucru permite definirea unui ambient propriu. Un fisier .profile tipic va arata astfel :

PATH=$HOME/bin:/etc:/bin:/usr/bin

USER=jim

MAIL=/usr/spool/mail/$USER

export PATH USER MAIL

: prevent other users from writing to the terminal

mesg n

: set default file creation mask

umask 027

echo People currently logged on:

who

echo 'Hello chris: nice to see you again'

Un exemplu de shell script.

Exemplu :

Script-ul cptree face o copie al unui intreg arbore de directoare, pe multe sisteme acesta este disponibil ca si un program standard, cu mult mai multe optiuni, dar acest script este destinat doar exemplificarii unui script mai mare.

: Copy a directory hierarchy

: With optional argument '-v' echo filenames

if test '$1' = -v

then

ECHO=echo

VERBOSE=-v

shift

: 'replaces $1 by $2, $2 by $3, etc'

else

ECHO=:

fi

if test $# -ne 2

then

echo usage: cptree from to

exit 1

fi

: if first argument is a directory copy

: all files to second argument

if test -d $1

then

if test -f $2

then

: second argument exists, but is not a directory

echo cptree: $2 is not a directory

exit 1

elif test ! -d $2

: second argument does not exist - create it

then

$ECHO mkdir $2

: Will echo the command if -v was set,

: otherwise just a comment

mkdir $2

fi

for FILE in `ls -a $1`

: To make sure we get files beginning with '.'

do

if test $FILE = . -o $FILE = ..

then

: ignore this directory and

: directory

continue

fi

: call cptree recursively, passing on VERBOSE option

cptree $VERBOSE $1/$FILE $2/$FILE

done

elif test -r $1

then

: just copy a non-directory

$ECHO cp $1 $2

cp $1 $2

else

echo cptree: cannot read $1

exit 1

fi








Politica de confidentialitate





Copyright © 2022 - Toate drepturile rezervate