CATEGORII DOCUMENTE |
Ce este shell
Cum se foloseste shellul
Citeva exemple de shell
Shell este numele generic pentru interpretorul de comenzi al Linux/Unix. Interfata LINUX de tip linie de comanda este desemnata prin intermediul termenului shell. Daca ati lucrat in DOS sau fereastra DOS in Windows, probabil ati dat comenzi de genul "dir", "copy" etc. De fapt, ati lucrat in interpretorul de comenzi al DOS‑ului.
"Shell" tradus inseamna "scoica" sau "invelis". Shell‑ul este un invelis pentru sistem, o interfata intre sistem si utilizator. Figura 1
Figura 1
Daca ati vazut vreodata un fisier cu extensia "BAT", ati vazut un script DOS. In DOS, fisierele de comenzi au extensia "BAT" (batch file). Fisierele de comenzi in Linux - scripturile - nu au extensie. Ele au drepturi de executie. Daca scripturile DOS sunt interesante, scripturile Unix‑ului sunt adevarate programe.
Faptul ca nu trebuie sa tastam din nou aceeasi secventa de comenzi de mai multe ori, ci le scriem intr‑un script si executam scriptul cand avem nevoie, este util, dar nu destul. De aceea, scripturile au posibilitatea sa contina blocuri conditionale si bucle (if, for, while). Acesta le face foarte puternice, in apropiate cu programele limbajelor de nivel inalt.
Mai mult, scripturile nu trebuie compilate -
Daca vreti sa schimbati ceva,
Cei care au creat Unix, nu au vrut un shell fix, ci interschimbabil, in functie de preferintele utilizatorilor si de scopurile pentru care se folosea shell‑ul respectiv. Primul shell de Unix a fost Bourne shell, prescurtat sh.
Mai tarziu, Unix a ajuns de la Bell Labs si la Universitatea Berkeley din California, unde studentii au dezvoltat shell‑ul, realizind un limbaj de programare, asemanator cu C‑ul. L‑au denumit C shell (pronuntat "sea shell" - scoica de mare).
Cei de la Free Software Foundation vroiau si ei shell‑ul, dar C shell era restrictionat de AT&T la vremea aceea (1992). Totusi, colectia de soft pentru Unix a celor de la FSF, colectie numita GNU (care inseamna "GNU is Not Unix" - "GNU nu este Unix"), avea nevoie de un shell. Asa ca si l‑au scris ei: au luat Bourne shell, au luat cateva idei utile din C shell, si adaugind altele au creeat asa numitul Bourne Again shell, sau bash.
Alte variante de shell‑uri Unix/Linux sunt: tcsh, ash, zsh, pdksk, perl, tcl/tk, python etc., dar cel mai utilizat in Linux este bash
Inainte de a incepe macar sa incepcam sa scriem un script trebuie sa ne asiguram ca avem instalat bash-ul. Verificam daca avem bash instalat: dati comanda bash la linia de comanda. Daca bash este instalat, se va porni. Daca nu, se va afisa "command not found".
Si acum pe cai
De obicei, o comanda Linux contine trei segmente:
Numele comenzii;
Optiunile comenzii;
intrare si/sau iesire (INPUT si/sau OUTPUT)
De exemplu, listarea, in format lung, a continutului directorului /dev:
ls -l /dev
Desigur, nu toate cele trei segmente sunt obligatorii, in functie de ce dorim comanda sa faca, dar numele comenzii este minimul necesar:
ls
sau
ls -l
sau
ls /dev
Dati comanda:
ls /dev | more
Sa presupunem ca ati vrut de fapt less in loc de more, dar nu vreti sa tastati inca odata comanda. Executati comanda:
^more^less
(Semnul ^ se afla de obicei pe tasta cu numarul 6) Observati ce s‑a intamplat: shell‑ul a schimbat more in less in ultima comanda data si a re‑executat comanda. Asta inseamna ca shell‑ul a memorat comanda anterioara.
Nu este necesar sa tastati aceeasi comanda inca odata. Bash memoreaza comenzile pe care i le-ati dat; trebuie doar sa apasati sageata‑sus, si apare ultima comanda pe care ati executat‑o. Daca apasati inca odata tasta sageata‑sus, apare penultima comanda.
Dati acum comanda:
!ls
Shell‑ul a re‑executat linia de comanda ce incepea cu ls. Aici, semnul exclamarii se numeste "bang". Dar daca dati "bang‑bang"? Incercati, fara ls:
Ce face bang‑bang? Re‑executa ultima comanda.
Daca doriti ca o comanda sa devina cea mai recenta in lista memorata, incercati:
!ls:p
Asta va face ca ultima comanda ce incepea cu ls sa devina cea mai recenta din lista memorata (din cauza :p)
In comanda urmatoare, <TAB> semnifica tasta TAB, adica sa apasati TAB dupa ce ati scris "ls /et", apoi apasati tasta ENTER (simbolizat in exemplu cu <ENTER>). Dati comanda:
ls /et<TAB><ENTER>
Observati ca Linux scaneaza radacina ("/") si gaseste un singur fisier sau director al carui nume incepe cu "et" (este directorul etc), asa ca ii completeaza automat numele in linia de comanda. Dati acum:
ls /d<TAB>lp<TAB><TAB>
Observati ce s‑a intamplat. Incercati acum:
ls /d<TAB>fd<TAB><TAB>y
Observati rezultatul.
Puteti folosi cateva caractere speciale, numite wildcards, pentru a usura lucrul cu numele de fisiere. Iata cele mai folosite:
* (asterisc)
? (semn de intrebare)
(backslash)
Asteriscul tine locul a oricare si oricate caractere (chiar si nici unul). De exemplu, comanda
ls a*.txt
va lista numele tuturor fisierelor a caror nume incepe cu "a" si se termina cu ".txt", din directorul curent. In schimb, comanda
ls a?.txt
va afisa toate fisierele a caror nume incepe cu "a", urmat de un (unul si numai unul) caracter oarecare si se termina cu ".txt". Asta deoarece "?" tine locul unui singur caracter, obligatoriu unul, orice caracter. "??" tine locul a doua caractere si asa mai departe. Puteti combina asteriscul cu semnul intrebarii, de exemplu:
ls a?z*.t?t
Ce putem face daca numele fisierului include asterisc sau semnul intrebarii? De exemplu, avem fisierul a*z? Comanda
ls a*z
se apuca si listeaza toate fisierele a caror nume incepe cu "a" si se termina cu "z", ceea ce nu este ce am dorit. ca sa explicitam ca nu folosim asteriscul ca si caracter special, ci ca unul normal, ii punem un caracter escape in fata, caracterul backslash, astfel:
ls a*z
Desi puteti sa dati nume din acestea fisierelor dvs. (nume care sa includa "?", "*", "/" etc.), nu este indicat, deoarece veti lucra mai greu cu ele.
Afisati continutul fisierului /etc/passwd cu comanda cat. Observati ca fisierul nu incape pe ecran, asa ca comanda cat vi‑l deruleaza rapid si ramane vizibil numai ultimul ecran de text.
Incercati acum comanda
more /etc/passwd
Aceasta comanda, more, va afiseaza continutul fisierului pe mai multe ecrane; daca apasati Enter, textul defileaza cu o linie mai jos. Apasarea lui Space determina defilarea in jos cu o pagina.
Executati comanda
ls -l /dev | more
Observati ca listarea se opreste la primul ecran; daca apasati tasta spatiu, se afiseaza ecranul urmator, si tot asa. Ce se intampla? Comanda ls -l /dev genereaza o lista lunga de text, de mai multe ecrane. In schimb, nu‑l afiseaza pe monitor, ci il transmite comenzii more. Comanda more primeste textul generat de ls, ca si cum ar fi un fisier, si il afiseaza pe mai multe ecrane. Am transmis iesirea unei comenzi (ls) spre intrarea altei comenzi (more), prin operatorul pipe ("teava" - "|").
Variabilele sunt cuvinte cu ajutorul carora putem accesa o valoare. Ele sunt utile pentru ca, in sistem, putem memora diferite valori si le putem da nume concludente, de exemplu contror, in loc sa stim pe de rost valoarea - de exemplu, 47295.
Variabilele au nume si valoare. De exemplu, numele variabilei poate fi cutie. Daca punem o minge in cutie, putem spune ca aceea este valoarea - sau continutul - variabilei cutie.
Definirea unei variabile consta din 3 parti:
Un nume de variabila;
Operatorul de asignare "=";
Valoarea variabilei;
Exemplu:
nume_var=valoare_var
Unde, nume_var este numele variabilei, iar valoare_var este valoare ei care se atribuie variabilei.
Folosind analogia cu cutia si cu mingea, avem:
nume_var este "cutia",
iar
valoare_var este "mingea"
Observatie: dupa cum vedeti, intre numele variabilei, valoarea variabilei si operator nu exista spatiu.
Variabilele se pot accesa folosind prefixul "$" (simbolul dolar).
In shellul bash exista doua tipuri de variabile: variabile de mediu si variabile locale.
Variabilele de mediu sunt cele create de sistem si sunt de obicei definite in fisierul /etc/profile:
$HOME: directorul alocat la intrarea in sesiune
$PATH: lista directoarelor unde se cauta pt. executia unei comenzi
$PS1: defineste prompter-ul asociat utilizatorului: # - supervizor, $ - utilizator
$LOGNAME: numele utilizatorului
$MAIL: numele directorului de posta
$SHELL: numele interpretorului de comenzi
$TERM: tipul terminalului
Variabilele de mediu au efect asupra tuturor utilizatorilor
Variabilele locale sunt cele definite de utilizator si, de obicei, sunt de gasit in fisierul local ~/.bashrc. Aceste variabile sunt locale si apartin utilizatorului care le poate modifica.
Variabilele locale afecteaza doar utilizatorul care le-a definit.
Observatie: un uitati ca Linux face diferentiere intre literele mari si mici.
echo $SHELL
Rezultatul este:
/bin/bash
Incercati acum comanda
echo SHELL
Rezultatul este
SHELL
Observati ca daca nu se pune prefixul "$", sistemul nu considera cuvantul respectiv ca variabila.
Acest lucru inseamna ca variabila numelui nume_var se extinde la valoarea variabilei valoarea_var cand se pune simbolul $ in fata ei.
Destul cu povestile, sa facem un script! Pentru asta, trebuie sa:
Deci, sa cream un script cu numele s1, care sa contina comenzile:
clear
ls -l /dev | more
echo "Am listat continutul lui /dev"
Executati scriptul. Ce face acest script? Sterge ecranul (clear), listeaza continutul lui /dev in format extins (ls -l /dev) pe mai multe ecrane, apoi scrie pe ecran textul "Am listat continutul lui /dev" (echo "Am listat continutul lui /dev").
Scriptul de mai sus nu este foarte flexibil. Ce se intampla daca dorim sa listam continutul directorului /etc ? Scriptul nostru stie sa listeze numai continutul lui /dev.
Creati un alt script, cu numele test, care sa contina comenzile:
clear
echo "Fisierul executat: $0"
echo "Primul parametru: $1"
echo "Al doilea parametru: $2"
echo "Al treilea parametru: $3"
echo "Numarul parametrilor: $#"
Executati scriptul. Apoi executati comanda (scriptul cu parametrii):
./test animal 75 barabula 11
Ce se intampla? Parametrii comenzii (in cazul nostru, animal, 75, barabula si 11) se pot folosi in script, deoarece shell‑ul le transmite scriptului ca si variabile. Incercati scriptul si cu alti parametri.
Haideti sa facem scriptul nostru mai flexibil. Vom schimba numele directorului de listat intr‑unul care sa‑l selectam la executia scriptului. Editati fisierul l:
clear
ls -l $1 | more
echo "Am listat continutul lui $1"
Executati scriptul cu parametrul /dev, apoi cu /etc.
Afisati continutul fisierului text /etc/passwd. Acest fisier contine detalii despre utilizatorii din sistem (parolele sunt tinute in alt fisier). Vrem sa cream un script u care sa afiseze numele de cont (coloana 1) si numele complet al utilizatorilor (coloana 5). Asta presupune filtrarea fisierului. Vom folosi comanda cut pentru filtrare.
Creati si editati fisierul u, cu continutul:
cut -f 1,5 -d: /etc/passwd
Salvati, faceti‑l executabil si executati scriptul u. Observati ca comanda din script a pastrat prima si a cincia coloana. De unde stie care sunt coloanele? I‑am specificat delimitatorul dintre coloanele din fisier, cele doua puncte(":").
Acum vrem sa inlocuim cele doua puncte din rezultat cu " - " (spatiu - liniuta - spatiu), pe fiecare linie. Vom folosi editorul de linie sed. Iata comanda care face acest lucru:
cut -f 1,5 -d: /etc/passwd | sed -e 's/:/ - /'
Optiunea -e al lui sed ii spune sa foloseasca sirul de caractere de dupa el (intre doua caractere apostrof) ca si expresie de filtrare pentru editor. Sed va inlocui caracterele dintre primul si al doilea slash ("/") cu caracterele dintre al doilea si al treilea slash. Este necesar sa punem comanda intre apostrofuri sau ghilimele, ca shell‑ul sa n‑o interpreteze, ci sa‑l trateze ca si text ce trebuie transmis programului sed. Expresia de filtrare este o expresie regulata ("regular expression", "regexp"), care au propria sintaxa.
Modificati scriptul, ca sa contina comanda:
cut -f 1,5 -d: /etc/passwd | sed -e 's/:/ - /' | more
Executati scriptul. Observati efectul comenzii date.
Sa dezvoltam in continuare scriptul. Dorim sa cream un raport - un fisier text - care sa contina conturile si numele utilizatorilor asociati; insusi numele fisierului raport sa contina si data la care a fost creat. Iata scriptul:
cut -f 1,5 -d: /etc/passwd | sed -e 's/:/ - /' > $1_`date +%d_%m_%Y`
Observatie: daca vreti sa impartiti linia in doua, dar interpretorul de comenzi sa nu execute partial comanda cand dati Enter in mijlocul liniei, inainte de a da Enterul intermediar se pune caracterul backslash ("") ca .
Compunerea numelui de fisier de iesire: primul parametru din linia de comanda, liniuta jos, apoi data. Comanda care compune data este intre caractere "accent grav" ("`"). Il puteti gasi, de obicei, pe tasta cu tilda ("~"), sub tasta Esc. Accentul grav ii spune shell‑ului sa execute textul ca si o comanda Linux si sa insereze rezultatul comenzii in locul unde s‑a apelat comanda (dupa $1_, in cazul nostru). Puteti incerca comanda date cu acesti parametri si in afara scriptului, la inia de comanda. Caracterele procent specifica parametrii pentru date: %d este ziua, %m luna, iar %Y anul in format extins (patru cifre). Daca ar fi %y, ar fi doar ultimele doua cifre din an.
Executati scriptul cu parametru, astfel:
./u utilizatori
Exemplele de mai jos prezinta elemente aditionale ale shell, in special varianta de shell bash.
# - exemplul 0
# parametrii: $0(numele scriptului), $1, $2, .
clear
ls -l $1
echo 'Ati dat comanda $0 pe $1'
Scriptul genereaza copia unui fisier inainte de editare.
# - exemplul 1
if cp '$1' '#$1' # continua cu ramura then daca cp reusita
then
joe '$1'
else
echo 'Nu am putut crea copia de siguranta'
fi
# - exemplul 2
if test -f '$1' # sau if [ -f "$1" ]
then
joe '$1'
else
echo 'Fisierul $1 nu exista'
fi
Observatie: comanda test permite evaluarea oricarei expresii utilizand valoarea acelei expresii in locul codului de terminare al comenzii.
# - exemplul 3
sum=0
for i in 1 2 3 4 5 6 7 8 9 10
do
sum=`expr $sum + $i`
done
echo 'Suma = $sum'
# - exemplul 4
echo -n 'Introduceti valoarea: '
read value
echo 'Ati introdus: $value'
Comparatia se poate face cu operatorii = , !=, -n (lung != 0), -z (lung = 0).
# - exemplul 5
echo -n 'Introduceti string1: ' # -n nu trece la linie noua
read string1
echo -n 'Introduceti string2: '
read string2
if [ $string1 = $string2 ]
then
echo 'string1 egal cu string2'
else
echo 'string1 diferit de string2'
fi
Comparatia se poate efectua cu operatorii operatorii-eq (=), -ge(>=), -le(<=), ne (!=), -gt (>), -lt(<).
# - exemplu 6
echo -n 'Introduceti nr1: '
read nr1
echo -n 'Introduceti nr2: '
read nr2
if [ $nr1 -eq $nr2 ]
then
echo 'nr1 egal cu nr2'
else
echo 'nr1 diferit de nr2'
fi
-d - fis. Este director
-f - fis este fisier
-s - numele are lung >0
-r - are atribut de citire
-x - are atribut de executie
# - exemplu 7
if [ -d $1 ]
then
echo '$1 este director'
else
echo '$1 nu este director'
fi
! (not), -a (and), -o (or)
Forma generala:
for varcrt in list
do
corp
done
# exemplu 9 - creaza o copie a unui director
mkdir copie
for filename in `ls`
do
cp $filename copie/$filename
if [ $? -ne 0 ] # $? este valoarea returnata de cp
then
echo 'copierea lui $filename a esuat'
fi
done
10.10. Instructiunea whileForma generala: while expr do corp done |
# exemplu 10 - aduna primele 5 numere pare contor=0 rez=0 while [ $contor -lt 5 ] do increment=`expr $contor * 2` rez=`expr $rez + $increment` done echo 'rez=$rez' |
Forma generala:
until expr
do
corp
done
Forma generala:
if [ expr ]
then
instr1
elif [ expr ]
instr2
else
instr3
fi
# - exemplu 12
echo -n 'VAR=: '
read VAR
if [ $VAR = 'Yes' ]
then
echo 'Val. este Yes'
elif [ $VAR = 'No' ]
then
echo 'Val. este No'
else
echo 'Val. invalida'
fi
10.13. Instructiunea case
Forma generala:
case str in
str1 | str2)
instr1;;
str3 | str4)
instr2;;
.
*) instr3;;
esac
# - exemplu 13
case $1 in
01 | 1) echo 'Ian';;
02 | 2) echo 'Febr';;
12 | 12) echo 'Dec';;
*) echo 'Par Inv';;
esac
Efectueaza o iesire fortata din for, while, until
Efectueaza o iesire fortata din script; poate returna o valoare; 0 - executie cu succes.
Definitia:
numefunctie ()
Apel: numefunctie pa1 pa2 .
# - exemplu 16
dm()
dm $2
dm $3
echo $1
Apel
./ex16 1 12 2
Raspuns:
Dec
Febr
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 1811
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved