This is an old revision of the document!


Curs 06 - Automatizarea sarcinilor. Shell scripting

Demo

Ce este un script?

Un script shell este un program scris într-un fișier text format din combinații de comenzi și instrucțiuni specifice unui interepretor de comenzi (unui shell). Shell-ul este un interpretor de comenzi care faciliteaza accesul utilizatorului la resursele sistemului de operare.

Cum arata un script shell:

#!/bin/bash
echo Noi suntem banul si stema
  • Ce inseamna #!/bin/bash?

Secventa de caractere (shebang) care este prezenta tot timpul la inceputul unui script si care indica interpretorul scriptului (in exemplul dat fiind shell-ul Bash).

  • Cum cream si rulam un script?

Putem deschide command line-ul, cream un fisier cu extensia .sh (good practice), pe care ulterior il editam folosind orice editor text (vim, Sublime etc.), caruia ulterior trebuie sa ii dam drepturi de executie (chmod pentru a schimba si ls -l pentru verificare). La sfarsit, putem rula script-ul ca pe orice executabil.

student@uso:~/Documents$ vi script.sh
student@uso:~/Documents$ chmod +x script.sh
student@uso:~/Documents$ ls -l script.sh
-rwxr-xr-x 1 student student 44 nov  3 17:06 script.sh  
student@uso:~/Documents$ ./script.sh
Noi suntem banul si stema
  • De ce shell scripting?

Script-urile ofera posibilitatea de automatizare a sarcinilor putand utiliza o serie mai mare de comenzi laolalta. De asemenea, structurile repetitive (for, while) si cele decizionale (if, else) pot fi implementate usor folosind shell scripting. Operatorii logici sunt si ei des folositi pentru a inlantui mai multe comenzi, la fel ca si pipe-urile (“|”) - folosite pentru a folosi output-ul unei comenzi in comanda urmatoare.

Mai jos este un demo cu comenzile cele mai folosite pentru shell scripting si pentru a automatiza lucrul in linia de comanda.

Comanda grep

Comanda grep extrage liniile care contin o expresie regulata data dintr-un fisier.

student@uso:~/Documents$ cat cap_si_pajura | grep frate
Am fost frate pentru frate. x2
Ca nu e si fratele tau
Am fost frate pentru frate. x2
Am fost frate pentru frate. x2
<code>

==== Comenzile head si tail ====
Comenzile head si tail sunt folosite pentru afisarea primelor/ultimelor linii sau caractere dintr-un input

<code>
student@uso:~/Documents$ cat cap_si_pajura | grep frate | head -2
Am fost frate pentru frate. x2
Ca nu e si fratele tau
student@uso:~/Documents$ cat himalaya | grep bani | tail -3
Tot aşa găsesc eu banii şi în vârful munţilor.
Eu fac bani şi-n Himalaya
Unde fac eu bani pachete, duşmanii culeg doar pietre…

Comanda seq

Comanda seq este folosita pentru a genera o secventa de numere. Flagul -s este folosit pentru a stabili caracterul care delimiteaza numerele. Delimitatorul implicit este ‘\n’.

student@uso:~$ seq 4
1
2
3
4
student@uso:~$ seq -s " " 1 2 5
1 3 5

In comanda de mai sus 1 reprezinta numarul de la care pornim numaratoarea, 2 este incrementul, iar 5 este numarul la care ne oprim. Optiunea -f este folosita pentru a afisa secventa intr-un anumit format.

student@uso:~$ seq -f "Star Wars Episode %01g" 3
Star Wars Episode 1
Star Wars Episode 2
Star Wars Episode 3
student@uso:~$

Comanda cut

Comanda cut este folosita pentru a taia aceeasi sectiune din fiecare linie a unui input si a afisa aceste parti ale liniilor. De exemplu, pentru urmatorul fisier vrem sa afisam doar numele filmelor, nu si anul in care au avut loc premiera fiecaruia.

student@uso:~$ cat asok.txt
Inception 2010
Parasite 2019
Se7en 1995
Goodfellas 1990
Gladiator 2000
Alien 1979
student@uso:~$ cut -d " " -f 1 asok.txt
Inception
Parasite
Se7en
Goodfellas
Gladiator
Alien
student@uso:~$

Optiunea -f se foloseste selecta ce coloane din input vrem sa fie afisate, iar optiunea -d defineste delimitatorul dintre coloane.

Comanda sed

Comanda sed se poate folosi cu mai multe scopuri, sed fiind un stream editor avansat. Se foloseste in principal pentru insertii sau steregere de caractere intr-un input.

student@uso:~$ cat text.txt
Noi ştim că unu ori unu fac unu,
dar un inorog ori o pară
nu ştim cât face.
Ştim că cinci fără patru fac unu,
dar un nor fără o corabie
nu ştim cât face.
student@uso:~$ sed 's/unu/bani/' text.txt
Noi ştim că bani ori unu fac unu,
dar un inorog ori o pară
nu ştim cât face.
Ştim că cinci fără patru fac bani,
dar un nor fără o corabie
nu ştim cât face.
student@uso:~$

In exemplul de mai sus, prima aparitie de pe fiecare linie a cuvantului “unu” este inlocuita cu “bani”. Caracterul s care vine imediat dupa sed indica operatia care se face pe input (substitution)

Mai jos sunt schimbate toate aparitiile cuvantului “unu”.

student@uso:~$ sed 's/unu/bani/g' text.txt
Noi ştim că bani ori bani fac bani,
dar un inorog ori o pară
nu ştim cât face.
Ştim că cinci fără patru fac bani,
dar un nor fără o corabie
nu ştim cât face.
student@uso:~$

Comanda se poate folosi si pentru a sterge linii din input.

student@uso:~$ sed '3d' text.txt
Noi ştim că unu ori unu fac unu,
dar un inorog ori o pară
Ştim că cinci fără patru fac unu,
dar un nor fără o corabie
nu ştim cât face.

Comanda de mai sus sterge a treia linie. Mai jos se sterge linia care contine cuvantul secventa de caractere “cinci”.

student@uso:~$ sed '/cinci/d' text.txt
Noi ştim că unu ori unu fac unu,
dar un inorog ori o pară
nu ştim cât face.
dar un nor fără o corabie
nu ştim cât face.

Folosind regex-uri, putem face pattern matching destul de usor folosind aceasta comanda. De exemplu, comanda de mai jos sterge linia care contine string-ul “nu” la inceputul unui sir.

student@uso:~$ sed '/^nu/d' text.txt
Noi ştim că unu ori unu fac unu,
dar un inorog ori o pară
Ştim că cinci fără patru fac unu,
dar un nor fără o corabie
student@uso:~$

Comanda wc

Comanda wc este folosita pentru a numara liniile, cuvintele sau carcterele dintr-un input.

student@uso:~$ cat yossa
Can you live without answers? All of you, ask that of yourself. Can you live without answers?
Because if you cannot, then most assuredly you will invent your own answers and they will comfort
you. And all those who do not share your view will by their very existence strike fear and hatred
into your heart.
student@uso:~$ wc yossa
  4  56 307 yossa

4 este numarul de linii, 56 este numarul de cuvinte, iar 307 este numarul de caractere.

for, while, if, else

Inainte de a prezenta aceste instructiuni, trebuie sa intelegem ce presupune folosirea caracterului $ in niste situatii.

$(command) - se inlocuieste cu output-ul comenzii “command”

student@uso:~$ echo Output-ul este $(echo acesta)
Output-ul este acesta
student@uso:~$

$(var) - valoarea ce se gaseste in variabila var

student@uso:~$ a=5
student@uso:~$ echo $a
5
student@uso:~$

Instructiunea if

Sintaxa lui if este urmatoarea:

if [ conditie ]
then
   comenzi
fi

Pe langa aceasta mai putem avea si if-else sau if-elif-else-fi spre exemplu

if [ conditie ]
then
   comenzi pentru conditie true
else
   comenzi pentru conditie false
fi
if [ conditie1 ]
then
   comenzi pentru conditie1 true
elif [ conditie2 ]
then
   comenzi pentru conditie2 true
else
   comenzi pentru conditie2 false
fi

Mai jos este un exemplu de folosire a unui if intr-un script. Sintaxele diferite de mai sus functioneaza la fel ca cele de pe care le stim de la programare. In schimb, conditiile sunt cele care necesita un plus de atentie.

#!/bin/bash

a=6
b=7
if [[ $a -eq $b ]]
then
		echo "Numerele sunt egale"
elif [[ $a -gt $b ]]; 
then
		echo "a mai mare decat b"
else
		echo "b mai mare decat a"
fi

student@uso:~$ ./script.sh
b mai mare decat a
student@uso:~$

Instructiunile for si while pot fi folosite atat in cadrul terminalului in comenzi, dar pot fi folosite si in script-uri. Mai jos este un exemplu cu loop-ul for folosit intr-o comanda

student@uso:~$ for v in $(seq 1 4); do echo linia $v; done
linia 1
linia 2
linia 3
linia 4

For poate fi folosit si intr-un script.

student@uso:~$ cat script.sh
#!/bin/bash

a=0;
for v in $(seq 1 4)
do
	a=$(($a + $v));
done
echo $a;
student@uso:~$ ./script.sh
10
student@uso:~$

Script-ul de mai sus afiseaza suma numerelor de la 1 la 4. In acelasi mod poate fi folosit si while:

#!/bin/bash

i=0;
while [ $i -le 3 ]
do
   	 		echo $i
    			i=$(($i+1))
done

Script-ul afiseaza valorile de la 0 la 3

student@uso:~$ ./script.sh
0
1
2
3
student@uso:~$

Mai jos avem un script care pune la sfarsitul liniilor pare dintr-un text un string:

#!/bin/bash

nr_linii=$(wc -l text.txt | cut -d " " -f 1)
i=0
while [ $i -le $nr_linii ]
do
    			if [[ $(($i%2)) -eq 0 && $i -gt 0 ]]
    			then
   	 			sed -i "$i s/$/ yeah/" text.txt
    			fi
    			i=$(($i+1))
done

Se observa ca acest script foloseste atat un while, cat si un if, precum si comanda sed.

student@uso:~$ cat text.txt
California, rest in peace
Simultaneous release
California, show your teeth
She's my priestess
I'm your priest
student@uso:~$ ./script.sh
student@uso:~$ cat text.txt
California, rest in peace
Simultaneous release yeah
California, show your teeth
She's my priestess yeah
I'm your priest
student@uso:~$
uso/cursuri/curs-06.1605543030.txt.gz · Last modified: 2020/11/16 18:10 by ebru.resul
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0