[Bourne Shell]
[Previous page][Section contents page][Pagina urmatoare]

Introducere


Generalitati. Variante de shell


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.

    Tipuri de operatori


    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.


    Comanda test


    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") 

    Operatori pentru fisiere


    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 ]

    Operatori pentru siruri de caractere


    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?
    1. [ $sir1 ] ; echo $? 
    2. [ -n $sir3 ] ; echo $? 
    3. [ $sir1=$sir4 ] ; echo $? 
    4. [ "$sir4"="$sir3" ] ; echo $? 
    5. [ -z $sir4 ] ; echo $?


    Care dintre comenzile urmatoare vor avea rezultat un exit status zero?

    1. [ "$sir1"!="$sir2" ] ; echo $? 
    2. [ -z "$sir3" ] ; echo $? 
    3. [ -n "$sir4" ] ; echo $? 
    4. [ "$sir1"="$sir3" ] ; echo $? 
    5. [ "sir4" ] ; echo $?

    Operatori pentru tipul integer


    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:
    1. [ "$int1" -gt "int2" ] ; echo $? 
    2. [ "$int2" -lt "$int3" ] ; echo $? 
    3. [ "$int4" -le "$int1" ] ; echo $? 
    4. [ "$int3" -eq "$int4" ] ; echo $? 
    5. [ "$int4" -ne "$int1" ] ; echo $?
  • Fie atribuirile:

  • v1=007
    v2=7
    Ce vor afisa fiecare dintre comenzile:
    1. [ "$v1" = "$v2" ] ; echo $? 
    2. [ "$v2" -eq "$v2" ] ; echo $?

    Operatori pentru tipul boolean


    Operatorii utilizati sunt:
    1. ! <expresie> : expresie falsa? 
    2. <expresie1> -a <expresie2> ambele adevarate? 
    3. <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. 

  •  

     


    Operatori pentru tipul logic


    Operatorii utilizati sunt:
    1. && 
    2. ||


    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.
    1. 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.
    2. 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 "\".

    3. Exemplu: [ \("$luna" -le 12 \) -a \("$ziua" -lt 32 ]\) || \
      echo "Data invalida $an $luna $ziua" 

    Operatori aritmetici


    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:
    1. 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.
    2. Deoarece operatorul "*" are o semnificatie speciala pentru shell, trebuie ca atunci cand vrem sa facem o operatie de inmultire, sa folosim caracterul de evitare \.

    3. 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.
    4. Cea mai folosita operatie este incrementarea: var=`expr $var + 1`
    [Previous page][Section contents page][Next page]