Documente Academic
Documente Profesional
Documente Cultură
Programare Shell
1. Introducere
Shell-ul este o componenta a sistemului de operare care permite interpretarea comenzilor UNIX
tastate de catre utilizator in terminalul UNIX, sau in consola. A interpreta aceste comenzi inseamna
de fapt a transforma comenzile utilizator in procese care se pot executa la nivelul procesorului. De
exemplu la tastarea comenzii date care permite afisarea datei curente procesorul va trebui sa
citeasca informatiile referitoare la ora sistemului de la ceasul procesorului, sa converrteasca aceste
sdate intr-un format inteligibil, si apoi sa tipareasca aceste date aflate intr-un format citibil la
terminalul utilizatorului. Din acest exemplu se poate trage concluzia ca toate comenzile UNIX nu se
pot realiza direct la nivelul procesorului, ci este nevoie de un mediu care sa permita aceasta
translatare, transpunere din formatul de comanda UNIX in operatii care se pot efectua la nivelul
procesorului.
Cuvantul shell defineste in limba engleza termenul de cochilie. Aceasta “cochilie” poate fi
vizualizata in schita de mai jos care prezinta componentele sistemului de operare UNIX :
Asa cum se poate obseva din figura de mai sus shell-ul UNIX este un limbaj de comenzi. Deci
elementele constitutive ale shell-ului sunt comenzile UNIX. Echivalentul literar si stiintific in
limba romana pentru cuvantul shell este de interpretor de comenzi.
Pentru sistemele de operare de tip UNIX shell-ul poate fi interpretat ca fiind aplicatia Konsole,
pentru sistemele de operare Windows 9x este command.com, pentru NT este cmd.exe iar
echivalentul cu interfata grafica este explorer.exe.
Pentru sistemele de operare de tip UNIX exista mai multe tipuri de shell cum ar fi Bourne Shell,
Bourne Again Shell, Z Shell, C Shell, Korn shell, etc.
http://en.wikipedia.org/wiki/Operating_system_shell
http://en.wikipedia.org/wiki/Unix_shell
Multe din proprietatile shell-ului sunt utilizate cu succes in limbaje de programare precum Perl,
Ruby sau Python.
Pentru a identifica ce shell utilizati dumneavoastra in terminal incercati comanda : echo $0.
1.2 Bash
Bash reia o mare parte din shell-ul original Linux (Bourne Shell) si integreaza numeroase ameliorari
provenite din shell-urile Ksh si Csh.
Acest program este cu acces gratuit si a fost portat sub Windows . Mediul care a permis portarea
sub Windows se numeste Cygwin.
ovidiu:x:280:1000:ovidiu:/home/ovidiu:/bin/bash
Shell-urile disponibile pe calculatorul dumneavoastra pot fi gasite in directorul /bin . Orice shell are
in compunerea denumirii sale literele sh . Descoperiti shell-urile disponibile pe calculatorul
dumneavoastra !
Un script shell este de fapt un fisier text care contine comenzi care pot fi intelese de catre
interpretorul dumneavoastra de comenzi. Aceasta lista de comenzi poate fi o lista in adevaratul sens
al cuvantului, sau poate fi o combinatie de instructiuni specifice, variabile si bineinteles comenzi
UNIX.
#!/bin/bash
clear
ls -l
echo “Ati 'curatat' ecranul si apoi ati expus continutul de fisiere si directoare al directorului curent”
Dupa cum se poate vedea in exemplul de mai sus, scriptul nu contine decat trei comenzi aflate
fiecare pe cate un rand din scriptul de mai sus.
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
#!/bin/bash
a=0
k=1
for i in `ls`
do
if [ -f $i ]
then
cat $i
a=`expr $a + $k`
fi
done
echo "Sunt $a fisiere"
In exemplul de mai sus se face o afisare a tuturor fisierelor din directorul curent, dupa care se face
afisarea numarului de fisiere. Apar variabile cum ar fi a, i si k. Apar de asemeni instructiuni : if, for,
dar si comenzi uzuale unix : echo, cat, ls.
Dupa expunerea de mai sus, care a avut drept scop familiarizarea cu notiunea de script shell, in
continuare va fi expus fluxul care descrie cum se creeaza si se ruleaza un asemenea script.
1. Deschideti un editor preferat, in care veti scrie un fisier numit HelloWorld.sh . Numele
oricarui fisier ce contine un script shell este compus din numele pe care-l intentionati la care
se adauga extensia .sh .
2. Prima linie cu care va trebui sa inceapa acest fisier este :
#!/bin/bash
Rolul acetei linii este de a indica faptul ca acest fisier nu este unul obisnuit, ci este unul care
contine un script care poate fi interpretat de catre shell-ul specificat.
3. Specificati continutul fisierului dumneavoastra. In cazul de fata nu trebuie decat singura
linie :
echo 'HelloWorld ! '
4. Salvati fisierul astfel creat.
5. Acordati dreptul de executare fisierului astfel creat :
$ chmod +x HelloWorld.sh
6. Executati scriptul astfel creat :
$ ./HelloWorld.sh
Mai jos este prezentat un mod simplu de creare si rulare a scriptului de mai sus :
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
$ chmod +x Helloworld.sh
$ ./HelloWorld.sh
HelloWorld !
O remarca importanta se refera la comentariile pentru scripturile shell. Acestea se pot introduce
oriunde in textul sursa al scriptului. Comentariile se introduc cu ajutorul simbolului diez #. Ele se
pot introduce fie pe linie noua, fie ca ultimul sir de caractere dintr-o linie de cod.
Exemple :
#!/bin/bash
echo “Hello!”
#acesta este un comentariu
#!/bin/bash
echo “Hello!” # acesta este alt comentariu
#!/bin/bash
echo “Hello!” # acesta nu este un comentariu bun deoarece instructiunea de pe acelasi rand este ignorata $a=ls
In continuare gasiti cateva exemple de scripturi shell formate dintr-o succesiune de comenzi. Testati
aceste scripturi !
#!/bin/bash
clear
echo -n Dumneavoastra utilizati un sistem
uname
echo
echo -n Versiunea kernelului dumneavoastra este
uname -r
3. Variabile si operatii
Spre deosebire de alte limbaje de programare, cum ar fi C/C++ sau Java, in scripturile shell nu este
nevoie de declararea explicita a variabillelor. Pur si simplu efectuati o atribuire acolo unde este
necesar si folositi aceasta variabila acolo unde se cere.
variabila = valoare
Orice variabila este folosita mai departe prefixand numele variabilei de simbolul $ (dolar) .
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
Exemplu :
a=1
echo “Am gasit $a fisiere speciale”
#!/bin/bash
expr 1 + 2
a=2
expr $a "*" 6
b=5
expr $a "-" $b
c= expr $a "*" $b
echo "$c"
Intotdeauna accesul la valoarea unei variabile se face cu ajutorul simbolului $ (dolar). Atunci cand
dorim sa facem calcule simple cu o anumita variabila este recomandat sa se utilizeze notatia
$variabila, deoarece intr-o asemenea situatie este nevoie sa se acceseze valoarea varibilei. La
atribuirea de valori unei variabile nu se foloseste simbolul $, deoarece nu trebuie accesata valoarea
variabilei, ci trebuie modificat continutul acesteia.
Operatiile aritmetice si de compararea pe care le permite spre evaluare comanda expr sunt :
− adunare : +
− scadere : -
− inmultire: *
− impartire : /
− restul impartirii : %
− comparare : > >= < <= != =
Aceasta comanda permite de asemeni lucrul cu expresii complexe, care contin paranteze.
Introducerea parantezelor se face cu ajutorul lui \ (slash). Exemplul de mai jos sugereaza cum se
poate utiliza aceasta comanda :
$ expr \( 5 + 2\)
7
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
Scripturile shell permit folosirea variabilelor de mediu definite de catre sistemul dumneavoastra de
operare. Referirea la aceste variabile de mediu se face in mod analog cu referirea variabilelor
uzuale, cu ajutorul simbolului $ . Atentie la numele acestora care contine doar majuscule.
Utilizatorul poate defini propriile sale variabile de mediu. Problema care se pune este legata de
scopul de a defini noi variabile de mediu.
Cu scopul de a crea programe interactive care permit citirea de date introduse de catre utilizator a
fost introdusa comanda read. Acesta comanda are sintaxa urmatoare :
read nume_variabila
Efectul comenzii este de a citi ceea ce introduce utilizatorul si de a atribui variabile nume_variabila
valoarea citita.
$ read variabila
5
$ echo $variabila
5
$ read nume prenume
Aritoni Ovidiu
$ echo "Numele dumneavoastra este $nume $prenume"
Numele dumneavoastra este Aritoni Ovidiu
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
5. Structuri condiţionale
5.1 Teste IF
Pentru a executa o instructiune doar atunci cand este indeplinita o conditie se utilizeaza comnada if.
Sintaxa acestei comenzi este :
if [ conditie ];
then
instructiune (grup de instructiuni)
fi
Exemplu
#!/bin/bash
if [ $varsta -ge 18 ];
then
echo "Sunteti o persoana cu drept de vot"
echo " ! "
fi
Pentru a introduce alternative la testele IF se utilizeaza else. Similarul lui else if (conditie) din
limbajele de programare este elif.
Exemplu
#!/bin/bash
if [ $varsta -ge 18 ];
then
echo "Sunteti o persoana cu drept de vot"
echo " ! "
else
echo "Nu aveti drept de vot"
fi
#!/bin/bash
if [ $varsta -ge 18 ];
then
echo "Sunteti o persoana cu drept de vot"
echo " ! "
elif [ $varsta -ge 14 ];
then
echo "Nu aveti drept de vot,dar aveti carte de identitate"
fi
Testul if poate testa mai multe conditii . Acestea pot sa fie in relatie de :
− conjunctie : [ conditia1 ] && [ conditia2 ]
− disjunctie : [ conditia1 ] || [ conditia2 ]
#!/bin/bash
#!/bin/bash
if [ ! -d /folder ];
then mkdir /folder
fi
5.5 Case
Similarul instructiunii case din linbajele de programare este case. Acesta are sintaxa :
case “$variabilaOptiune” in
multimea1) instructiuni1 ;;
multimea2) instructiuni2 ;;
multimea3) instructiuni3 ;;
.............................................
multimean) instructiunin ;;
*) instructiuniDEFAULT ;;
esac
Variabila dupa care se exprima optiunea poate sa fie intr-o anumita multime. Aceasta multime poate
avea un singur element, de exemplu :
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
case “$x”
1) echo “Optiunea 1 ! “ ;;
.......
De asemeni multimea poate fi o multime de numere sau litere, sau alte elemente :
case “$x”
[ 0-9 ]) echo “Numere naturale cu o singura cifra !” ;;
[ 10-99 ]) echo “Numere naturale cu dou cifre !” ;;
*) echo “Alte numere !“ ;;
esac
case “$x”
[ am, nam, bam ] : echo “$x” ;
...........................
esac
Exemple
#!/bin/bash
#!/bin/bash
case "$year" in
[0-9][0-9])
year=19${year}
years=`expr $year - 1901`
;;
[0-9][0-9][0-9][0-9])
years=`expr $year - 1901`
;;
*)
echo 1>&2 Year \"$year\" out of range ...
exit 127
;;
esac
5.6 Select
Instructiuna select este o extensie a instructiunii case. Spre deosebire de case, lista de valori posibile
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
pentru care se poate face o optiune este specificata la inceputul instructiunii. In plus aceasta
instructiune asigura un tratament unitar pentru oricare dintre optiunile alese .
Un merit deosebit este acela ca instructiunea permite crearea de meniuri in mod automat.
$ ./scriptSELECT.sh
Care este sistemul de operare preferat ?
1) Windows
2) Linux
3) BSD
4) MAc Os
5) MS DOS
#? 3
Sistemul dumneavoastra este BSD .
6. Structuri repetitive
Structurile repetitive sunt similare celor din limbajele de programare : for, while, until.
O structura repetitiva este utilizata intr-un program daca :
− se doreste introducerea unei informatii corecte de catre utilizator. In acest caz structura
repetitiva va cere introducerea acelei informatii pana cand ea este corecta.
− se doreste repetarea unei anumite actiune de un numar bine stabilit sau nu de ori.
Atunci cand se doreste repetarea unei anumite instructiuni de un numar fix de ori se utilizeaza
instructiunea for, iar cand numarul nu este fixat se utilizeaza instructiunile while respectiv do-until.
While se utilizeaza pentru a executa o anumita instructiune atata timp cat este verificata o anumita
conditie.
Sintaxa :
while [ conditie ] ;
do
intstructiuni
done
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
Exemple
1. Exemplul urmator calculeaza suma numerelor introduse de catre utilizator atata timp cat
numerele introduse sunt mai mici sau egale decat 10 :
#!/bin/bash
read x
s=0
while [ $x -le 10 ];
do
s=`expr $s + $x`
read x
done
echo "Suma este $s"
2. Exemplul urmator numara de cate ori a fost introdusa optiunea DA. Ciclul while se opreste la
introducerea altui sir de caractere diferit de “DA”.
#!/bin/bash
read r
u=1
x=0
while [ "$r" = "DA" ]
do
x=` expr $x + $u `
read r
done
Until inseamna “pana cand” , ceea ce inaseamna ca ciclul se va repeta pana cand conditia
specificata va fi indeplinita.
until [ conditie_care_trebuie_indeplinita ]
do
instructiuni
done
Exemple
1. Scriptul urmator are acelasi efect cu exemplul 1 explicat in cadrul ciclului while.
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
#!/bin/bash
read x
s=0
until [ $x -ge 10 ];
do
s=`expr $s + $x`
read x
done
echo "Suma este $s"
2. Scriptul urmator are acelasi efect cu exemplul 1 explicat in cadrul ciclului while.
#!/bin/bash
read r
u=1
x=0
until [ "$r" != "DA" ]
do
x=` expr $x + $u `
read r
done
echo "Contorizarea = $x"
Structura repetitiva for este utilizata atunci cand se doreste repetarea unei anumite instructiuni sau
bloc de instructiuni de numar bine precizat de ori.
Exemple
#!/bin/bash
s=0
for i in 1 2 3 4 5 6 7 8 9 10
do
s=`expr $s +$i`
done
Remarcati ca in acest script shell este utilizata comanda seq. Aceasta comanda construieste
o secventa de numere. De exemplu seq 100 , creeaza o secventa care contine primele 100 de
numere naturale. Comanda seq 41 56 creeaza o secventa de numere ce contine toate
numerele cuprinse intre 41 si 56, inclusiv extremitatile 41 respectiv 56. O optiune
importanta pe care o are aceasta comanda este de a permite construirea de secvente de
numere construite prin incrementare . De exemplu comanda seq 1 3 100 permite afisarea
de numere de la 1 la 100 din 3 in 3, incepand cu 1.
Cititi pagina de manual a comenzii seq si rulati cele cateva exemple de mai sus pentru o mai
buna intelegere a acestei comenzi.
#!/bin/bash
s=0
#!/bin/bash
s=0
7. Transmiterea parametrilor
Orice comanda UNIX se apeleaza prin numele sau urmat de anumite optiuni si de parametri.
De exemplu comanda de copiere a unui fisier fis.txt intr-un director DirectorA este :
cp fis.txt DirectorA
0 1 2
0 : comanda
1 : parametrul 1
2 : parametrul 2
Parametrii se utilizeaza pentru a nu cere introducerea de date suplimentare de catre utilizator dupa
lansarea procesului care efectueaza o anumita comanda, in felul acesta asigurandu-se o atomicitate a
procesului si continuitate.
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
Este asadar recomandabil sa se utilizeze pe cat posibil scripturi care utilizeaza tehnica transmiterii
de parametri. Pentru a pasa un parametru unui script shell se procedeaza analog cu parmetrarea
comenziilor UNIX :
Acesti parametrii pot fi referentiati in cadrul programului scriptului cu ajutorul unor variabile
speciale dupa cum urmeaza :
#!/bin/bash
$ ./parametri.sh a b c d
Ati transmis 4 parametrii dupa cum urmeaza :
Parametrul 1 : a
Parametrul 1 : b
Parametrul 1 : c
Parametrul 1 : d
Putem afisa toti parametrii printr-un singur apel : a b c d
8. Redirectari
Iesirea standard a orciarei comenzi UNIX este ecranul. In anumite situatii este necesar ca iesirea
unei comenzi, adica raspunsul ei, sa fie utilizat ca si parametru pentru o alta comanda. Pentru a
utiliza iesirea unei anumite instructiuni ca si parametru se utilizeaza tehnica redirectarii asupra
careia se concentreaza acest paragraf.
Fenomenul descris printr-o inlantuire ca cea exprimata in titlul acestui paragraf poate fi sintetizat
intr-un singur cuvant : PIPE. Un fisier in care un proces poate scrie, iar un alt proces poate citi se
numeste fisier de tip PIPE. Pentru executia unei comenzi shell in marea majoritate a cazurilor se
creeaza un proces care va executa cerintele acelei comenzi. Atunci cand dorim ca procesul creat
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
pentru a rezolva o anumita comanda, sa transmita rezultatele lui unui alt proces se creeaza un fisier
PIPE in care un proces va scrie date iar altul le va citi.
Exemplu :
Linia
cat fisier.txt | wc -l
creeaza doua procese. Primul proces trateaza comanda de afisare a fisierului fisier.txt. Rezultatele
afisarii vor fi depuse in fisierul PIPE creat si simbolizat prin | (linie verticala) . Comanda wc -l , va
fi tratata printr-un alt proces care va citi datele din fisierul PIPE creat, numarand liniile care se afla
scrise in fiserul PIPE .
Exemplul urmator este justificativ pentru acest tip de redirectare. Mai jos se poate analiza un mod
de a tipari continutul tuturor fisierelor dintr-un anumit director :
$ cat `ls`
....
Continutul tuturor fisierelor
Rezultatele unei comenzi constituie “iesirea” acelei comenzi. Redirectarea rezultatelor se poate face
fie catre un fisier fie catre o alta iesire.
Modalitatea de a redirecta iesirea unei comenzi este de a utiliza simbolul dupa numele comenzii a
carui rezultat doriti sa il redirectati :
comanda > altOutput
Daca se realizeaza redirectarea cu ajutorul lui > intr-un fisier atunci acest fisier va fi creat chiar daca
el nu exista. Daca fisierul exista deja pe disc atunci continutul acestuia va fi inlocuit complet de
output-ul comenzii anterioare. Daca se doreste sa se inscrie in fisier la sfarsitul lui atunci se va
folosi >> . Pentru detalii studiati exemplele urmatoare :
Exemple
Pentru a evita afisarea tuturor mesajelor de eroare la terminalul standard este adesea util sa afisam
aceste mesaje intr-un anumit fisier text. Astfel aceste mesaje pot fi studiate si ulterior, proces care
este deosebit de util.
$ mkdir TestRedirectareErori
$ cd TestRedirectareErori
:~/TestRedirectareErori$ echo 'A B C' | xargs mkdir
:~/TestRedirectareErori$ man ls > ls.txt
Reformatting ls(1), please wait...
:~/TestRedirectareErori$ man cat > cat.txt
Reformatting cat(1), please wait...
:~/TestRedirectareErori$ ls
A B C cat.txt ls.txt
:~/TestRedirectareErori$ cat `ls` 2> erori.txt
CAT(1) User Commands CAT(1)
NAME
cat - concatenate files and print on the standard output
SYNOPSIS
cat [OPTION] [FILE]...
.....................................................................................................
Urmeaza continutul celor doua fisiere ls.txt si cat.txt .
Programul urmator arata cum se poate scrie la cele doua iesirii standard : stdout si stderr .
#include <stdio.h>
int main()
{
fprintf(stdout,"message on stdout\n");
fprintf(stderr,"message on stderr\n");
fprintf(stdout,"2nd message on stdout\n");
return 0;
}
Creati un fisier redirectari.c care va contine programul sursa de mai sus. Compilati si rulati
programul de mai sus. Pentru a pune in evidenta mesajele de tip eroare redirctati stderr spre un
fisier numit erori.txt .
[LABORATOR DE SISTEME DE OPERARE 1] Aritoni Ovidiu
9. Functii
Ca majoritatea limbajelor de programare si scripturile shell pot contine functii ce sunt definite in
interiorul acestora si care pot fi apelate ulterior.
function nume( ) {
Apelul unei functii se face prin numele sau. Unei functii i se pot transmite anumiti parametri ca unui
script shell .
10.Referinte WEB