1 of 31

Cursul #6

Automatizarea sarcinilor. Shell Scripting

1

2 of 31

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.

Jamie Zawinski (JWZ)

2

3 of 31

Suport de curs

Capitolul 13 - Automatizarea sarcinilor

    • https://github.com/systems-cs-pub-ro/carte-uso/releases

3

4 of 31

Ce este un Script Shell

  • O înșiruire de comenzi shell
  • Este interpretat de shell: se interpretează pe rând fiecare comandă
  • Pe lângă comenzi externe, sunt folosite și comenzi interne, precum if, for, while, case
  • Facilități shell precum command expansion

4

5 of 31

Perspective pentru shell scripting

  • quick’n’dirty: dacă e prea complicat trebuie apelat la un limbaj de programare
  • folosește comenzi și resurse existente
    • nu reinventa roata
  • există mai multe moduri de a face un lucru
    • alege cel mai bun pentru situația dată
  • comunicare folosind text
  • atenție la caractere speciale
  • niciodată nu vei ști suficient de mult shell scripting: documentează-te, exersează și îmbunătățește

5

6 of 31

Rulare script

  • bash myscript.sh
  • chmod a+x myscript.sh && ./myscript.sh

  • #! -> shebang
    • indică interpretorul scriptului

6

7 of 31

Exemplu Shell Script

7

#!/bin/bash

�sudo mdutil -a -i off

sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist

sudo mdutil -a -i on

sudo mdutil -E /

8 of 31

Utilizarea Shell Scripting

  • automatizare
    • înlănțuire comenzi pentru un rezultat mai complex
    • task-uri repetitive
    • se rulează scriptul la nevoie
  • prelucrare de date
    • task-uri simple
    • quick’n’dirty
    • se folosesc filtre de text: prelucrează text (head, tail, grep, cut, tr, awk, sed)

8

9 of 31

One liner

  • Înlănțuirea unor comenzi
  • De obicei legate prin operatorul pipe ( | )
  • Ceva util _acum_, nu neapărat permanent, in schimb un shell script poate fi refolosit
  • Orice shell script poate fi un one liner

  • http://www.bashoneliners.com

9

10 of 31

Dezvoltarea de scripturi shell

10

11 of 31

Comenzi existente

  • Nu trebuie să fie complicat
    • acolo unde o comandă are opțiuni utile, se folosesc acelea
  • Comenzi de afișare: NU se folosesc în scripturi
    • ls, ps, df, ifconfig, w
  • Comenzi de prelucrare: se folosesc în scripturi
    • stat, find, fișierele din /proc, grep

11

12 of 31

Înlănțuire de comenzi

  • pipe (operatorul |)
  • expandarea comenzilor: $( ... )
  • folosire nouă a comenzilor existente
  • preluarea outputului unei comenzi
    • la intrarea standard a alteia (pipe)
    • ca argument al alteia (expandare)

12

13 of 31

Variabile

  • stocare de valori
  • nu au un tip de date
  • $?: codul de ieșire al ultimei comenzi
  • $$: PID-ul procesului curent
  • $#: numărul de parametri în linia de comandă
  • $1, $2, ...: al N-lea parametru

13

14 of 31

Controlul fluxului

  • instrucțiuni de decizie: if, case
  • intrucțiuni de ciclare: for, while

14

15 of 31

Construcția if

  • De obicei, if comanda1 e de forma:
    • If test conditie

  • Verifică dacă există fisierul:

15

if comanda1; then

comanda2

else

comanda3

fi

if test –f ”$file”; then

echo ”File $file exists.”

fi

  • Verifică dacă există argumente:

if test ”$#” –ne 1; then

echo ”Usage: $0 argument”

exit 1

fi

16 of 31

Construcția for

  • List e o construcție

asemănătoare cu o

listă

  • Parcurgerea utilizatorilor din sistem�

16

for i in list; do

command1

command2 ...

done

for user in $(cut –d ‘:’ –f 1); do

nlogins=$(last ”$user” | grep ”^$user” | wc -l)

echo ”User $user logged in $nlogins times recently.”

done

17 of 31

Construcția while read

  • parsing cu while read
  • mai puternic decât

cut, mai slab decât

awk

  • IFS: Input field separator
  • Extragerea numelui de utilizator și a directorului home�

17

while read field1 field2 ...; do

   command1

command2 ...

done < file�

IFS=”:”; while read user x y z t home v; do echo ”$user:$home”;

done < /etc/passwd

18 of 31

For vs while

  • for pentru elemente dintr-o listă
    • listă de utilizatori
    • listă de fișiere
  • while pentru parsing (împărțire elemente de pe o linie în bucăți)
    • date tabelare pentru prelucrare

18

19 of 31

Funcții

  • mai rar folosite ca într-un limbaj de programare
  • înglobarea unor acțiuni
  • se apelează similar unui script
  • pot avea argumente:
    • $1, $2 ... devin argumentele funcțiilor

19

20 of 31

Exemplu funcții

20

#!/bin/bash

OFFLINEIMAP=/opt/local/bin/offlineimap

LOGFILE=~/.log/offlineimap-cron.log

function check_alive()

{

ps -ef | grep "$OFFLINEIMAP" | grep -v grep > /dev/null 2>&1

}

�check_alive

if test $? -ne 0; then

nohup nice -n 19 "$OFFLINEIMAP" >> "$LOGFILE" 2>&1 &

fi

�exit 0

21 of 31

Expresii regulate - Utilizare

  • Regular expressions sau regex
  • Cautare (searching, pattern matching)
  • Validarea unui șir, a unui text, a unei intrări (număr de telefon, URL, nume de variabilă)
  • Substituirea unei expresii

21

22 of 31

Când să nu folosești expresii regulate

  • Când existe parsere
  • Când există aplicații, tool-uri, funcții mai bune pentru a face aceste lucru
  • Pentru anumite tipuri de date (adrese de e-mail, HTML): fie nu se poate, fie e foarte greu
  • Atunci când folosite abuziv, fac codul nementenabil/nelizibil

22

23 of 31

Metacaractere în expresii regulate

  • ^ : început de linie
  • $ : sfârșit de linie
  • . : orice caracter
  • [...] : set de caractere
  • ? : expresia anterioară cel mult o dată
  • * : expresia anterioară de oricâte ori posibil niciodată
  • + : expresia anterioară de oricâte ori cel puțin o dată
  • e1|e2 : expresia de dinainte sau cea de după

23

24 of 31

Exemple de expresii regulate

  • [_a-zA-z][_0-9a-zA-Z]*
    • Nume de variabilă/funcție
  • 07[:digit:]{8}
    • Număr de telefon
  • [:upper:][:alpha:]+
    • Numele unei persoane
  • ^[:upper:]{1,10}$
    • Linii conținând maxim 10 majuscule
  • [:digit:]{2}\.{pdf|png|svg}
    • Nume fișiere din două cifre și diferite extensii

24

25 of 31

Regex vs globbing

  • Globbing este folosit în shell, în special pentru filename expansion
  • Globbing poate fi considerat o formă mai slabă de expresie regulate
  • Expresiile regulate sunt puternice cu mai multe cazuri de utilizare și suport în majoritatea limbajelor/framework-urilor moderne

25

26 of 31

Suport expresii regulate

  • Utilitare shell: grep, awk, sed
  • Limbaje de programare: Perl, Python, PHP, Ruby, Java, JavaScript, C++11
  • Editoare: Vim, Emacs
  • Baze de date
  • Biblioteci cu suport de expresii regulate: Gnulib

26

27 of 31

Sfaturi Shell Scripting

  • nu folosiți shell scripting pentru ceea ce se face mai bine/ușor/eficient în Python, C, Java, Ruby, PHP etc
  • nu reinventați roata
  • folosiți ghilimelele când referiți valoarea unei variabile
  • folosiți cea mai bună opțiune (cut, grep, tr, awk, sed, while read) după nevoie
  • folosiți opțiuni de tip expresii regulate sau similare între apostrofuri

27

28 of 31

Regular Expressions Cookbook

  • Jan Goyvaerts, Stevemn Levithan
  • creatorii http://www.regular-expressions.info/, http://regexpal.com/
  • 2nd Edition
  • practică, multe „rețete”
  • o recenzie aici: https://blog.codinghorror.com/regular-expressions-for-regular-programmers/

28

29 of 31

Larry Wall

  • creatorul Perl
  • BDFL pentru proiectorul PERL
  • autorul programului patch
  • câștigător al International Obfuscated C Code Contest

29

30 of 31

Lua

  • limbaj de programare de scripting
  • paradigme multiple (la fel ca Python)
  • proiectat pentru a fi ușor încorporat în alte limbaje
  • API C simplu
  • limbaj de scripting pentru dezvoltatorii de jocuri
  • folosit de limbajul de scripting al utilitarului nmap
  • folosit pentru configurarea managerului de ferestre Awesome

30

31 of 31

Cuvinte cheie

  • variabile
  • variabile de mediu
  • one line
  • filtru de test
  • script shell
  • IFS
  • while read
  • for
  • if
  • expresii regulate
  • metacaractere

31