Genetica Comportamentului Uman - Conf. Univ. Dr. Corneliu Stanciu SH
Programare în Shell - Utilizarea Sistemelor de Operarepirofti/uso/uso-curs-10.pdf · VarianteShell...
-
Upload
dangkhuong -
Category
Documents
-
view
233 -
download
0
Transcript of Programare în Shell - Utilizarea Sistemelor de Operarepirofti/uso/uso-curs-10.pdf · VarianteShell...
Programare în ShellUtilizarea Sistemelor de Operare
Paul Irofti
Universitatea din Bucures,tiFacultatea de Matematică s, i Informatică
Department de InformaticăEmail: [email protected]
Motivat, ie
I de multe ori vrem să avem o singură comandă pentru un s, ir decomenzi
I comenzile sunt preponderent comenzi shell sau din sistem, nuoperat, ii logice sau aritmetice
I avem nevoie să scriem un program scurt rapidI vrem să funct, ioneze pe orice alt sistem pentru a repeta un set
de operat, ii de configurare sau administrareI bazat pe CS2043 Unix and Scripting de la Cornell University
(cursurile 9 s, i 10)
Variante Shell
I sh(1) – Bourne shellI printre primele shelluriI disponibilă oriunde în /bin/shI funct, ionalitate redusăI portabilitate
I csh(1) – C shell, comenzi apropiate de lucru în CI ksh(1) – Korn shell, bazat pe sh(1), succesor csh(1)I bash(1) – Bourne Again shell
I cea mai răspândităI există s, i în Windows 10I majoritatea scripturilor moderne scrise în bash(1)I acest rezultat a dus la o lipsă de portabilitateI proiect mare cu multe linii de cod s, i probleme de securitate
Variabile Shell
I două tipuri de variabile: locale s, i de mediuI variabilele locale există doar în instant,a curentă a shell-uluiI convent, ie: variabilele locale se notează cu litere miciI asignare: x=1 (fără spat, ii!)I x = 1: se interpretează drept comanda x cu argumentele = s, i 1I folosirea valorii unei variabile se foloses,te prin prefixarea
numelui cu $I cont, inutul oricărei variabile poate fi afis,at cu comanda
echo(1)
$ x=1$ echo $x1
Variabile de mediu
I folosite de sistem pentru a defini modul de funct, ionare aprogramelor
I shell-ul trimite variabilele de mediu proceselor sale copilI env(1) – afis,ează toate variabilele de mediu setateI variabile importante
I $HOME – directorul în care se t, in datele utilizatorului curentI $PATH – listă cu directoare în care se caută executabileleI $SHELL – programul de shell folosit implicitI $EDITOR – programul de editare fis, iere implicitI $LANG – limba implicită (ex. ro_RO.UTF-8)
I export(1) – se foloses,te pentru a seta o variabilă de mediuI printenv(1) – se foloses,te pentru a afis,a o variabilă de mediu
$ expo r t V=2$ p r i n t e n v V2$ echo $V2
Exemplu: Variabilă locală
$ LANG=ro_RO .UTF−8$ p r i n t e n v LANG$ echo $LANGro_RO .UTF−8$ bashbash −4.4$ p r i n t e n v LANGbash −4.4$ tbash : t : command not foundbash −4.4$ echo $LANG
bash −4.4$ e x i t
Exemplu: Variabilă de mediu
$ e xpo r t LANG=ro_RO .UTF−8$ p r i n t e n v LANGro_RO .UTF−8$ bashbash −4.4$ p r i n t e n v LANGro_RO .UTF−8bash −4.4$ echo $LANGro_RO .UTF−8bash −4.4$ tbash : t : comandă neg ă s i t ă
Variable expansion
Variabilele pot fi mai mult decât simplii scalariI $(cmd) – evaluează întâi comanda cmd, iar rezultatul devine
valoarea variabilei
$ echo $ (pwd)/home/ pau l$ x=$ ( f i n d . −name \∗ . c )$ echo $x. / b a t l e f t . c . / p c i e . c . / maxint . c . / e i s a i d . c
I $((expr)) – evaluează întâi expresia aritmetică, iar rezultatuldevine valoarea variabilei
$ x=1$ echo $ ((1+1))2$ echo $ ( ( x+1))2$ echo $ ( ( x<1))0
$ echo $ ( ( x++))1$ echo $ ( ( x++))2$ echo $((++x ) )4
Quoting
S, irurile de caractere sunt interpretate diferit în funct, ie de citare:I Single quotes ”
I toate caracterele îs, i păstrează valoareaI caracterul ’ nu poate apărea în s, ir, nici precedat de "\"I exemplu:
$ echo ’Am v a r i a b i l a $x ’Am v a r i a b i l a $x
I Double quotes ""I caractere speciale $ ‘ \ (opt, ional !)I restul caracterelor îs, i păstrează valoareaI exemplu:
$ echo "$USER has home i n $HOME"pau l has home i n /home/ pau l
I Back quotes “ – funct, ionează ca $()
$ echo "Today i s ‘ date ‘ "Today i s Wed May 2 18 : 00 : 08 EEST 2018
Înlănt,uirea comenzilor
I cmd1; cmd2 – înlănt,uire secvent, ială, cmd2 imediat după cmd1I cmd1 | filtru | cmd2 – ies, irea comenzii din stânga este
intrarea celei din dreapta operatorului |I cmd1 && cmd2 – execută a doua comandă doar dacă prima s-a
executat cu succesI cmd1 || cmd2 – execută a doua comandă doar dacă prima a
es,uatI exemplu:
$ mkdir a c t e && mv ∗ . docx ac t e /$ l s −lR | t e e f i l e s . l s t | wc − l$ s sh example . org | | echo " Connect ion f a i l e d !"
Scripting
DefinitionScript-urile sunt programe scrise pentru un mediu run-time specificcare automatizează execut, ia comenzilor ce ar putea fi executatealternativ manual de către un operator uman.
I nu necesită compilareI execut, ia se face direct din codul sursăI de acea programele ce execută scriptul se numesc
interpretatoare înloc de compilatoareI comenzile executate se mai numesc s, i byte-codeI astăzi granit,a dintre compilatoare s, i interpretatoare nu mai
este atât de clară (JIT, tiered compilation)I exemple: perl, ruby, python, sed, awk, ksh, csh, bash
Shebang (#!)
I reprezintă prima linie din orice script UnixI are forma #!/path/to/interpreterI exemple: #!/bin/sh, #!/usr/bin/pythonI pentru protabilitate folosit, i env(1) pentru a găsi unde este
instalat interpretatorulI exemple: #!/usr/bin/env ruby, #!/usr/bin/env perlI oriunde altundeva în script # este interpretat ca început de
comentariu s, i restul linei este ignorată (echivalent // în C)I introdusă de Denis Ritchie circa 1979
Exemplu: hello.sh
1. Scriem fis, ierul hello.sh cu comenzile dorite
#!/ b i n / sh
# Sa l u t e the u s e recho "He l l o , $USER!"
2. Permitem execut, ia: chmod +x hello.sh
3. Executăm:
$ . / h e l l o . shHe l l o , pau l !
Variabile speciale în scripturi
I $1, $2, ..., ${10}, ${11}, ... – argumentele în ordinea primităI dacă numărul argumentului are mai mult de două cifre, trebuie
pus între acoladeI $0 – numele scriptului (ex. hello.sh)I $# – numărul de argumente primiteI $* – toate argumentele scrise ca "$1 $2 ... $n"I $@ – toate argumentele scrise ca "$1" "$2" ... "$n"I $? – valoarea ies, irii ultimei comenzi executateI $$ – ID-ul procesului curentI $! – ID-ul ultimului proces suspendat din execut, ie
Exemple: argumente script
I add.sh – adună două numere
#!/ b i n / shecho $ ( ( $1 + $2 ) )
apel:
$ sh add . sh 1 23
I tolower.sh – imită funct, ia din C tolower(3)
#!/ b in / sht r ’ [A−Z ] ’ ’ [ a−z ] ’ < $1 > $2
apel:
$ echo "WHERE ARE YOU?" > sc reaming . t x t$ . / t o l owe r . sh sc r eaming . t x t decent . t x t$ ca t decent . t x twhere a r e you ?
Blocuri de control
Pentru scripturi mai complexe avem nevoie, ca în orice limbaj, deblocuri de control
I condit, ionale – if, test [ ], caseI iterative – for, while, untilI comparative – -ne, -lt, -gtI funct, ii – functionI ies, iri – break, continue, return, exit
If
I cuvinte cheie: if, then, elif, else, fiI exemplu ce foloses,te toate cuvintele cheie:
i f cmd1then
cmd2cmd3
e l i f cmd4then
cmd5cmd6
e l s ecmd7
f i
I o condit, ie este adevărată dacă comanda asociată esteexecutată cu succes ($?=0)
Exemplu: if
Caută în fis, ier date s, i le adaugă dacă nu le găses,te
#!/ b in / shi f g rep "$1" $2 > /dev/ n u l lthen
echo "$1 found i n f i l e $2"e l s e
echo "$1 not found i n f i l e $2 , append ing "echo "$1" >> $2
f i
apel:
$ . / t e x t . sh who decent . t x twho not found i n f i l e decent . t x t , append ing$ ca t decent . t x twhere a r e you?who
test sau [ ]
I nu dorim să testăm tot timpul execut, ia unei comenziI există expresii pentru a compara sau verifica variabileI test expr – evaluează valoarea de adevăr a lui exprI [ expr ] – efectuează aceias, i operat, ie (atent, ie la spat, ii!)I expresiile pot fi legate logic prin
I [ expr1 -a expr2 ] – s, iI [ expr1 -o expr2 ] – sauI [ ! expr ] – negat, ie
Expresii test: numere
I [ n1 -eq n2 ] – n1 = n2
I [ n1 -ne n2 ] – n1 6= n2
I [ n1 -ge n2 ] – n1 ≥ n2
I [ n1 -gt n2 ] – n1 > n2
I [ n1 -le n2 ] – n1 ≤ n2
I [ n1 -lt n2 ] – n1 < n2
Expresii test: s, iruri de caractere
I [ str ] – str are lungime diferită de 0I [ -n str ] – str nu e golI [ -z str ] – str e gol ("")I [ str1 = str2 ] – stringuri identiceI [ str1 == str2 ] – stringuri identiceI [ str1 != str2 ] – stringuri diferite
Expresii test: fis, iere
I -e path – verifică dacă există calea pathI -f path – verifică dacă path este un fis, ierI -d path – verifică dacă path este un directorI -r path – verifică dacă avet, i permisiunea de a citi pathI -w path – verifică dacă avet, i permisiunea de a scrie pathI -x path – verifică dacă avet, i permisiunea de a executa path
while
I execută blocul cât timp comanda cmd se execută cu succes
wh i l e cmddo
cmd1cmd2
done
I în loc de comandă putem avea o expresie de testI într-o singură linie: while cmd; do cmd1 cmd2; done
Exemplu: while
Afis,ează toate numerele de la 1 la 10:
i=1wh i l e [ $ i − l e 10 ]do
echo " $ i "i=$ ( ( $ i +1))
done
Sau într-o singură linie:i=1; while [ $i -le 10 ]; do echo "$i"; i=$(($i+1));done
until
I execută blocul cât timp comanda cmd se execută fără succes
u n t i l cmddo
cmd1cmd2
done
I în loc de comandă putem avea o expresie de testI într-o singură linie: until cmd; do cmd1 cmd2; done
for
I execută blocul pentru fiecare valoare din listă
f o r va r i n s t r 1 s t r 2 . . . s t rNdo
cmd1cmd2
done
I var ia pe rând valoarea str1, pe urmă str2 până la strNI de regulă comenzile din bloc (cmd1, cmd2) sunt legate de varI comanda for are mai multe forme, aceasta este cea mai
întâlnităI într-o singură linie:
for var in str1 str2 ... strN; do cmd1 cmd2; done
Exemplu: for
Compileză toate fis, ierele C din directorul curent
f o r f i n ∗ . cdo
echo " $ f "cc $ f −o $ f . out
done
Sau într-o singură linie:for f in *.c; do echo "$f"; cc $f -o $f.out; done
for tradit, ional
I formă întâlnite doar în unele shell-uri, nu este portabilI execută blocul urmând o sintaxă similară C
f o r ( ( i =1; i <=10; i++ ) )do
echo $ idone
I i ia pe rând toate valorile între 1 s, i 10I în exemplu, blocul afis,ează $i, dar pot apărea oricâte alte
comenziI într-o singură linie:
for (( i=1; i<=10; i++ )); do cmd1 cmd2; done
Case
I se comportă similar cu switch în C
ca se va r i np a t t e r n 1 )
cmd1cmd2; ;
p a t t e r n 2 )cmd3; ;
∗ )de fau l t cmd; ;
e sac
I pattern – poate fi un string sau orice expresie de shell (similarcu wildcards-urile folosite pentru grep(1))
Exemplu: case
Parsare subcomandă pentru un program SQL:
ca se "$1" i n’CREATE’ )
do_creat; ;
’ INSERT ’ )do_ in s e r t; ;
’SELECT ’ )do_se l e c t; ;
’USE ’ )do_use; ;
’DROP’ )do_drop; ;
∗)p r i n t_usage
e sac
read
I cites,te una sau mai multe variabile din stdinI sintaxă: read var1 var2 ... varN
$ read x y1 2$ echo $x $y1 2
I dacă nu este dată nici o variabilă, se as,teaptă să fie unasingură s, i pune rezultatul în $REPLY
$ readh e l l o$ echo $REPLYh e l l o
I citire line cu linie dintr-un fis, ier:cat foo.txt | while read LINE; do echo $LINE done