User Tools

Site Tools


unixmix:capitole:capitol-09

This is an old revision of the document!


Shell Scripting 2

Exerciții

Hands on (1)

  • Rulați următoarele comenzi pentru a genera niște fișiere și directoare.
cd ~
mkdir slash
cd $_
mkdir conf lib bin logs
cd conf
touch apache.conf bind.conf postfix.conf hosts services protocols
cd ..
cd lib
touch dns.so gethostbyname.so ip.so tcp.so smtp.so
cd ..
cd logs
mkdir apache bind postfix
touch apache/access.log apache/error.log bind/access.log bind/error.log postfix/access.log postfix/error.log
cd ..
cd bin
cp /bin/true apache
cp /bin/true postfix
cp /bin/true bind
cd ~
  • Găsiți toate fișierele și directoarele din directorul slash.
  • Găsiți toate fișierele ce au legătură cu apache.
  • Găsiți toate fișierele cu extensia .conf.
  • Găsiți toate fișirele .conf și creați un fișier de backup cu extensia .backup, exemplu apache2.conf → apache2.conf.backup.

* Găsiți toate numele de fișiere, fără calea lor.

  • Realizaţi un script numit checkfile.sh care:
    • primește ca argument un string și verifică dacă un fișier cu acest nume există pe disc în directorul curent
    • dacă fișierul nu există în directorul curent, acesta va fi creat cu numele dat ca argument
    • dacă fisierul există pe disc în directorul curent, acesta va fi redenumit în <nume-fișier-initial>_exista unde argument este argumentul transmis scriptului (numele fișierului)
    • Rulați scriptul de 2 ori cu același parametru.

Hands on (2)

  • Scrieți un script care primește doi parametri, start și count și afișează un număr de count procese începând de la indexul start, în ordinea crescătoare a PID-urilor. Hint: sort
  • Folosind sed scrieți un script care generează mail-uri în mod automat.

Ca date de intrare, creați un fișier cu structura:

nume,email
Alex,alex@example.com
Traian,traian@example.com

precum și un template, de genul:

Salut NUME!
...
Acest mesaj îți este adresat ție și numai ție.

Ca date de ieșire, scriptul va crea într-un director emails câte un fișier cu numele email personalizat pentru fiecare nume din fișierul dat.

  • Puteți face același lucru folosind bash? Dacă da, cum? Scrieți un alt script care folosește bash pentru înlocuiri.

Hands on (3)

  • Scrieți un script care crează copii de siguranță pentru toate fișierele din /etc sau un folder dat ca parametru, cu extensia .conf.
    • backupurile vor fi stocate într-un director cu numele: backup-YYMMDDHHmm din directorul curent (hint: date)
    • extensia copiilor de siguranță va fi .bak in loc de .conf

Hands on (4)

  • Programați ca peste 5 minute să fie creat un fisier executat în home-ul utilizatorului curent
  • Configurați ca scriptul de backup de la Hands on (3) să ruleze o dată la 10 minute.

Exerciții (2)

Exerciții

  1. Afișați conținutul pachetelor instalate în sistem al căror nume începe cu litera w.
    • Hint: dpkg -l <glob>
    • Pași de urmat:
      • Folosiți dpkg -l <glob> pentru a lista pachetele dorite.
      • Folosiți grep pentru a extrage doar pachetele instalate.
      • Folosiți tr și cut pentru a extrage doar numele pachetelor instalate.
      • Folosiți dpkg -L și expandarea comenzilor pentru a definitiva exercițiul.
  2. Afișați un șir de forma Last entry: $last_entry; Number of entries: $num_entries unde $last_entry este ultimul director precizat în variabila de mediu PATH, iar $num_entries reprezintă numărul de intrări din acel director.
  3. Realizați un script numit checkpar.sh care primește 2 parametri și îi afișează la ieșire. Dacă nu se dau exact 2 parametri, scriptul acesta afișează mesajul “Numărul de parametri este greșit”.
  4. Scrieți și rulați un script numit even.sh.
    • Scriptul primește ca argument un număr.
    • Scriptul va afișa mesajul par sau impar în funcție de paritatea numărului primit ca argument.
    • Scriptul se va întoarce cu eroare (exit 1) și va afișa un mesaj specific dacă se transmite un număr invalid de argumente (nici un argument sau mai mult de un argument).
    • Hint: http://tldp.org/LDP/abs/html/arithexp.html, mergeți la exemplul 1 și căutați “modulo”.
  5. Realizaţi un script numit checkfile.sh care:
    • primește ca argument un string și verifică dacă un fișier cu acest nume există pe disc în directorul curent
    • dacă fișierul nu există în directorul curent, acesta va fi creat cu numele dat ca argument
    • dacă fisierul există pe disc în directorul curent, acesta va fi redenumit în <nume-fișier-initial>_exista unde argument este argumentul transmis scriptului (numele fișierului)
    • Rulați scriptul de 2 ori cu același parametru.
  6. Realizați un script numit sum.sh care realizează suma primelor N numere naturale, unde N este dat ca parametru.
  7. Realizați un script care calculează suma numerelor de la 1 la N multiplu de M. N și M sunt transmise ca argumente în linia de comandă.
  8. Scrieți și rulați un script shell numit ls_boot.sh
    • Scriptul va folosi instrucțiuni repetitive pentru a afișa conținutul directorului /boot/.
    • Scriptul va afișa pentru fiecare intrare "fisier $nume_fisier" sau "director $nume_director".
      • $nume_fisier reprezintă numele fișierului (în cazul în care intrarea este fișier)
      • $nume_director reprezintă numele directorului (în cazul în care intrarea este director);
      • sirurile fisier și director vor fi afișate literal.

Exerciții (3)

sed

sed este un stream editor. Cel mai bine cunoscut pentru funcția de search and replace.

 
sed "s/foo/bar/g" in_file > out_file

Se poate adăuga parametrul -i pentru editare “in place” a fișierului:

 
sed -i "s/foo/bar/g" in_file

Înlocuirea se poate face prin expresii regulate:

sed -i "s/\^first/First/g" file
sed -i "s/[0-9]/X/g" file

În general, sintaxa se referă la o adresă (linii selectate) și la o acțiune asupra acelor linii:

# Pentru fiecare linie din text, dacă este între linia 3 și 4, printeaza-o; ignoră restul liniilor
sed –n `3,4p’ foo.txt
# Pentru fiecare linie din text, dacă este ultima linie, printeaza-o; ignoră restul liniilor
sed –n `$p’ foo.txt

Se pot aplica mai multe acțiuni asupra unui fișier, folosind parametrul -e la fiecare acțiune:

# Șterge liniile 4 și 2.
sed -e '4d' -e '2d' file

awk

awk este un întreg limbaj de procesare a textului.

În general, folosește un fișier de script pentru acțiuni, cu sintaxa:

awk –f awk.script foo.file

Există un bloc de BEGIN, unul de END și corpul scriptului.

Exemplu de script:

# Begin Processing
BEGIN {print "Print Totals"}

# Body Processing
{total = $1 + $2 + $3}
{print $1 " + " $2 " + " $3 " = "total}

# End Processing
END {print "End Totals"}

Rezultate:

Input   			Output
22 78 44			Print Totals
66 31 70			22 +78 +44 =144
52 30 44			66 +31 +70 =167
88 31 66			52 +30 +44 =126
				88 +31 +66 =185
				End Totals

Fiecar câmp dintr-o linie poate fi folosită ca o variabilă:

İnput	
1 clothing    3141
1 computers   9161
1 textbooks  21312
2 clothing    3252
2 computers  12321
2 supplies    2242
2 textbooks  15462
awk ‘if ($2 =="computers“){print}'sales.dat
Output
1 computers 9161
2 computers 2321	

Recapitulare

  • Scrieți un script care, cu ajutorul fișierului /etc/services, returnează ce serviciu rulează pe un port TCP/UDP.
#!/bin/bash

if [ $# -lt 2 ]; then
	echo Too few arguments
	exit 1
fi

line=$(cat /etc/services |tr -s '\t'| tr  '\t' ' '| grep " $1/$2")

if [ $? -eq 1 ]; then
	echo No such service
else
	echo Service name: $(echo $line|cut -d' ' -f1)
	echo Comment: $(echo $line|cut -d' ' -f3-)
fi
  • Scrieți un script care trimite mail-uri automate, pe baza unei liste de adreses și un tempalte.

Varianta bash:

addr:
Alex alexj@rosedu.org marti 10
Laura laura@rosedu.org miercuri 11

template:

echo Salut, $NUME!
echo 
echo Ne face plăcere să te invităm la cursul de CLI, care se vaține $ZI, la ora $ORA.
echo 
echo Ne vedem la Thales!
echo 
echo --
echo Organizația Răzvanilor Anonimi \(ORA\)
echo 

script:

#!/bin/bash

cat addr|
while read NUME EMAIL ZI ORA;do
	export NUME
	export ZI
	export ORA
	bash template
done


Varianta cu sed:

template:
cat addr|
while read __NUME__ __EMAIL__ __ZI__ __ORA__;do
	
	sed -e "s/__NUME__/$NUME/g" -e "s/__ZI__/$ZI/g" -e "s/__ORA__/$ORA/g" template|mail -s Invitație $EMAIL
done


script:
#!/bin/bash
cat addr|
while read NUME EMAIL ZI ORA;do
	
	sed -e "s/NUME/$NUME/g" -e "s/ZI/$ZI/g" -e "s/ORA/$ORA/g" template|mail -s Invitație $EMAIL
done

  • Scrieți un script care afișează doar fișierele utilizatorului thales din diectorul curent.
  • Scrieți un script care creează directorul numbers, iar în director creează 100 de fișiere ale căror nume este un număr cuprins între 100 și 199.
#!/bin/bash

mkdir numbers
pushd numbers
for i in $(seq 10 19); do
	touch $i
done
popd
  • Scrieți un script care afișează inode-ul unui fișier primit ca argument.
alexj@hathor ~/thales $ cat inode.sh 
#!/bin/bash

inode=$(stat $1 | head -n 3 | tail -n 1 | tr -s ' ' | cut -d' ' -f3)
echo Inode for $1 is $inode
  • Scrieți un script care afișează toate procesele din sistem care au cel puțin 2 procese copil.
  • Ce face variabila $PS1? Schimbați astfel încât $-ul din prompt să se transforme în #.
  • Scrieți un script care primește ca parametru numele unui director și are output-ul similar comenzii ls -ld pe acel director, însă dimensiunea afișată este dimensiunea reală.
#!/bin/bash

output=$(ls -ld $1)

first=$(echo $output | tr -s ' ' | cut -d' ' -f1,2,3,4)
last=$(echo $output | tr -s ' ' | cut -d' ' -f6-)
size=$(du -hsb $1 | tr '\t' ' ' | cut -d' ' -f1)
echo $first $size $last
  • Scrieți o comandă care adaugă la sfârșitul fișierului /etc/resolv.conf linia nameserver 8.8.8.8. Nu folosiți un editor text.
  • Scrieți o comandă care afișează numele tuturor fișierelor care au extensia .conf din directorul /etc.
  • Scrieți o comandă care scrie într-un fișier de log de fiecare dată când cineva a încercat să dea reboot la sistem și nu a reușit.
alias reboot='reboot || echo $(date) "reboot failed" >> /tmp/logg'
  • Scrieți un script care primește ca argument un director și un nume de grup și modifică grupul directorului în acesta.
    • Modificarea trebuie făcută și în toate subdirectoarele/fișierele din acesta.
    • Faceți astfel încât tot ceea ce se creează în acel director să moștenească grupul.
unixmix/capitole/capitol-09.1373623498.txt.gz · Last modified: 2013/07/12 13:04 by alexef