Introducere
Interpretorul de comenzi (shell-ul) al sistemului de operare Unix este programul ce
realizeaza doua functii de baza:
interpreteaza comenzile utilizatorului
asigura facilitati de programare shell puternice, apropiate de cele
ale limbajelor de programare de nivel inalt
In Unix exista mai multe implementari ale interpretoarelor de comenzi, printre care:
Bourne Shell (sh)
C Shell (csh)
Korn Shell (ksh)
Bourne Again Shell (bash - in Linux)
Odata cu deschiderea sesiunii de lucru Unix, utilizatorul foloseste
interpretorul de comenzi pentru comunicarea cu sistemul de operare. In
acest sens este afisat un sir de caractere (prompter), care poate fi modificat
de catre utilizator. Valoarea implicita a prompter-ului este $ pentru utilizatorii
obisnuiti si # pentru root (utilizatorul privilegiat). In continuare,
interpretorul de comenzi primeste comenzile de la utilizator, le decodifica,
stabileste conditiile de executare a acestora si apoi le lanseaza in executie.
Vom prezenta in continuare caracteristicile shell-ului Bourne.
Ca in toate limbajele de programare, operatorii permit programatorilor
sa utilizeze diverse operatii (aritmetice, logice, string, etc.) asupra
variabilelor. Bourne shell suporta trei tipuri de operatori:
aritmetici
de test
logici
Operatorii aritmetici sunt folositi doar pentru operatiile cu numere intregi.
Operatorii de test sunt folositi pentru operatii cu fisiere, cu variabile
string si cu intregi.
Aceasta comanda are forma: test <conditie>, sau [
<conditie> ], atunci cand este folosita ca parte a unei comenzi
if.
Obs: <conditie> are forma: [<operand1>][<operator>]<operand2>
Exemple:
test $sir1 != $sir2
Conditia va intoarce o valoare zero (de adevar) daca variabila sir1
este diferita ca valoare de variabila sir2 si o valoare diferita de zero
(fals) in caz contrar. Aceasta valoare poate fi verificata prin intermediul
lui exit status (parametrul special shell $?) care intoarce
valoarea de adevar a ultimei operatii.
Fie secventa de comenzi:
$ var1=15
$ var2=20
$ test $var1 = $var2 (ATENTIE: se lasa spatii inainte si dupa semnul =)
$ echo $?
(Se va afisa valoarea 1, care semnifica faptul ca testarea s-a incheiat
cu valoarea "false")
Acestia sunt operatori unari (cu un singur argument) si de cele mai multe ori argumentul este
numele unui fisier.
Dintre acesti operatori amintim:
-d <fisier> : este director?
-f <fisier> : este fisier obisnuit?
-g <fisier> : are setat group-ID?
-r <fisier> : poate fi citit?
-s <fisier> : este de lungime diferita de zero?
-w <fisier> : poate fi modificat?
-x <fisier> : este fisier executabil?
Exemple:
Fie comanda: ls -las ,cu efectul urmator:
total 5
4 drwxrwxrwx 1 root root 2048 Feb15 18:00 .
4 drwxrwxrwx 1 root root 2048 Feb15 18:10 ..
2 -rwxrwxrwx 1 razvan cib 1022 Dec15 17:45 .profile
1 -rwxrwxrwx 1 razvan cib 102 Feb16 17:45 stud.dat
2 -rwxrwxrwx 1 razvan cib 1102 Dec10 17:45 examen.dat
Fie comanda:
test -f stud.dat ; echo $?
Se va afisa 0, avand in vedere ca stud.dat este intr-adevar fisier obisnuit.
Ce se va afisa pentru urmatoarele comenzi?
test -d examen.dat
test -x examen.dat
test -s examen.dat
[ -r examen.dat ]
[ -w stud.dat ]
Observatie In general, este bine ca variabilele shell folosite in testare sa fie
incadrate de ghilimele: "<variabila>"
Operatorii folositi pentru operatii cu siruri de caractere sunt:
<sir1> : este sirul <sir1> nenul?
-n <sir1> : are sirul <sir1> lungimea diferita de zero?
-z <sir1> : are sirul <sir1> lungimea zero?
<sir1>=<sir2> : este sirul <sir1> identic cu <sir2>?
<sir1>!=<sir2> : este sirul <sir1> diferit de <sir2>?
Exemple:
Atribuire cu valoare null: $ var=
Comanda test $var=hello ; echo $? nu este corecta deoarece $var trebuie
sa apara intre ghilimele; deci corect este test "$var"=hello ; echo $?.
(Explicatie. comanda test asteapta 3 parametri: $var, =, hello.
Conversia efectiva a lui $var la valoarea sa se face inainte de interpretarea
intregii comenzi. Deoarece valoarea lui $var este null, va rezulta interpretarea
unei comenzi de genul test =hello, de unde rezulta eroarea). Ghilimelele
au rolul de separator pentru caracterul null.
Fie atribuirile:
sir1=dan
sir2=maria
sir3=dan
sir4=
Care dintre comenzile urmatoare vor produce mesaje de eroare la executie?
- [ $sir1 ] ; echo $?
- [ -n $sir3 ] ; echo $?
- [ $sir1=$sir4 ] ; echo $?
- [ "$sir4"="$sir3" ] ; echo $?
- [ -z $sir4 ] ; echo $?
Care dintre comenzile urmatoare vor avea rezultat un exit status zero?
- [ "$sir1"!="$sir2" ] ; echo $?
- [ -z "$sir3" ] ; echo $?
- [ -n "$sir4" ] ; echo $?
- [ "$sir1"="$sir3" ] ; echo $?
- [ "sir4" ] ; echo $?
Operatorii utilizati sunt:
-eq : se testeaza egalitatea lui int1 cu int2
-ge : se testeaza daca int1 este mai mare sau egal decat int2
-gt : se testeaza daca int1 este mai mare decat int2
-le : se testeaza daca int1 este mai mic sau egal decat int2
-lt : se testeaza daca int1 este mai mic decat int2
-ne : se testeaza daca int1 este diferit de int2
Exemple:
Fie atribuirile:
$int1=5
$int2=10
$int3=55
$int4=5
Ce vor afisa comenzile:
- [ "$int1" -gt "int2" ] ; echo $?
- [ "$int2" -lt "$int3" ] ; echo $?
- [ "$int4" -le "$int1" ] ; echo $?
- [ "$int3" -eq "$int4" ] ; echo $?
- [ "$int4" -ne "$int1" ] ; echo $?
Fie atribuirile:
v1=007
v2=7
Ce vor afisa fiecare dintre comenzile:
- [ "$v1" = "$v2" ] ; echo $?
- [ "$v2" -eq "$v2" ] ; echo $?
Operatorii utilizati sunt:
- ! <expresie> : expresie falsa?
- <expresie1> -a <expresie2> ambele adevarate?
- <expresie1> -o <expresie2> una dintre ele adevarata?
Exemple:
Fie atribuirile:
v1=5
v2=10
Ce va afisa comanda: [ !"$v1" -eq "$v2" ] ; echo $? (0)
Fie comanda: [ -f "fisier" -a -x "fisier" ]. Rezultatul va fi zero daca fisier
este atat fisier ordinar cat si executabil.
Fie comanda: [ "$var" -gt 1 -a "$var" -lt 90 ].Rezultatul este zero daca var
are o valoare cuprinsa intre 1 si 90 (strict).
Obs. Operatorul -a are o prioritate mai mica decat operatorii de comparatie pentru intregi.
Fie comanda: [ -r "stud" -o -d "stud" -lt 90 ]. Rezultatul este zero daca stud
poate fi citit sau daca este director.
Fie comanda: [ "$luna" -gt12 -o "$ziua" -gt 31 ]. Rezultatul este zero
daca luna este mai mare decat 12 sau daca ziua are o valoare
mai mare ca 31.
Operatorii utilizati sunt:
- &&
- ||
Acesti operatori permit executia unei comenzi in cazul in care comanda
precedenta se incheie cu succes sau nu. Astfel, daca avem urmatoarea constructie:
<comanda1> && <comanda2> , atunci <comanda2> este executata
daca exit status al comenzii <comanda1> este zero.
In mod asemanator, pentru constructia <comanda1> || <comanda2>
, <comanda2> este executata doar daca exit status al comenzii
<comanda1> este diferit de zero.
Exemple:
Fie comanda: [ -x "fisier_program" ] && fisier_program. Daca fisierul
fisier_program este executabil, atunci se lanseaza in executie.
Fie comanda: [ "$luna" -le 12 -a "$ziua" -lt 32 ] || \
echo "Data invalida $an $luna $ziua"
Daca luna sau ziua au valori invalide, atunci se executa comanda echo.
Observatii.
- Caracterul "\" (backslash) de la sfarsitul liniei anuleaza semnificatia
speciala a caracterului newline si il considera caracter whitespace.
Cu alte cuvinte, comanda se continua pe linia urmatoare.
- Parantezele "(",")" au semnificatie speciala si nu pot fi folosite in shellscript-uri
in scopul gruparii diverselor comparari. Pentru a ignora semnificatia speciala
a parantezelor intr-o comanda se foloseste tot caracterul de evitare "\".
Exemplu: [ \("$luna" -le 12 \) -a \("$ziua" -lt 32 ]\) || \
echo "Data invalida $an $luna $ziua"
Operatorii aritmetici sunt: +, -, *, /, % (impartire modulo).
Deoarece shell-ul nu are alt concept de data decat character string,
pentru a se putea face calcule aritmetice se va folosi comanda expr,
care informeaza shell/ul ca ce urmeaza trebuie evaluat ca expresie matematica.
Exemplu:
Fie:
x=9
x=$x+6
In acest caz, comanda echo "$x" va afisa 9+6 si nu rezultatul adunarii.
Comanda expr are de-a face numai cu numere intregi, astfel rezultatul
expr 15 / 6 va fi 2.
Observatii:
- Operanzii si operatorii dintr-o expresie aritmetica trebuie separati de
cel putin un spatiu. Astfel, daca scriem comanda de mai sus fara spatii
intre 15 si 6 : expr 15/6, rezultatul va fi 15/6.
- Deoarece operatorul "*" are o semnificatie speciala pentru shell, trebuie
ca atunci cand vrem sa facem o operatie de inmultire, sa folosim caracterul de evitare \.
Deci, daca x=3, y=4, z=5, atunci expr $x * $y este o comanda eronata, pe cand
expr $x \* $y \* $z va intoarce ca rezultat 60.
- Cea mai folosita operatie este incrementarea: var=`expr $var + 1`
|