Acest totorial este o scurtă recapitulare a noțiunilor referitoare la Bash ce au fost predate în cadrul cursului de Sisteme de Operare.
Bash (Bourne Again Shell) este un superset al Shell Command Language (SH) care permite o sintaxa mai usoara si mai lizibila si care aduce imbunatatiri. La baza, o comanda bash sau un script bash primeste date de intrare de la un terminal, de la un descriptor de fisier sau dintr-un sir de caractere, apoi ruleaza si produce date de iesire.
In bash nu exista decat variabile ca si structuri de date, care nu pot fi altceva decat siruri de caractere. Orice comanda sau operator care simuleaza alte structuri de date sau tipuri de variabile (de exemplu compararea intregilor sau declararea vectorilor) sunt doar implementari peste siruri de caractere care se pot comporta in anumite situatii ca si vectori sau intregi.
Orice script invocat intr-un shell trebuie sa contina la inceput un shebang. Shebang-ul incepe ca un comentariu, cu caracterul diez (#) dar este urmat de un semn de excalamare (!) si programul care va executa secventa de cod ce urmeaza. Fiecare secventa de cod poate fi apelata si in terminal. In cazul Bash, vom folosi ca shebang #!/bin/bash.
#!/bin/bash
# o variabila este referentiata fara '$' atunci cand se face asignarea
variabila="1"
# o variabila este referentiata cu '$' cand este nevoie de continutul ei
echo $variabila
#!/bin/bash
var1="1"
var2="2"
if [[ $var1 -gt $var2 ]]; then
# -gt sau "greater than"
echo "$var1 este mai mare decat $var2"
elif [[ $var1 -eq $var2 ]]; then
# -eq sau "equal"
echo "Variabilele sunt egale"
else
echo "$var1 este mai mic decat $var2"
fi
$> ./laborator1.sh
1 este mai mic decat 2
Similar pentru siruri de caractere
if [[ "$var1" == "$var2" ]]; then
echo "Sirurile sunt identice"
fi
Aplicarea conditiilor multiple ( folosind operatorii logici && (si) sau | (sau) ) |
if [[ $var1 -gt 0 ]] && [[ $var1 -lt $var2 ]]; then
echo "$var1 > 0 si $var1 < $var2"
fi
# sau for i in $(seq 1 5); do
for i in 1 2 3 4 5; do
echo -n $i;
done
$> ./laborator1.sh
1 2 3 4 5
#!/bin/bash
# Afiseaza toate argumentele primite din linia de comanda
echo $@
$> bash laborator1.sh 1 2 3
1 2 3
#!/bin/bash
# Afiseaza primul si al treilea argument
echo "$1 $3"
bash laborator1.sh 1 2 3
1 3
Trimiterea datelor de iesire catre un fisier:
#!/bin/bash
echo "Primul laborator" > fisier.txt
Date de intrare citite din fisier:
#!/bin/bash
while read line; do
echo $line
done < fisier.txt
Permite pasarea datelor de iesire de la o comanda ca date de intrare pentru alta comanda):
#!/bin/bash
# grep afiseaza liniile care contin text, iar wc le numara
grep "text" fisier.txt | wc -l
#!/bin/bash
exec 4>stdout.log
exec 2>error.log
exec 1>&4
echo "Fisier sau terminal?"
echo "Eroare" >&2
$> cat stdout.log
Fisier sau terminal
$> cat error.log
Eroare
$> ls
courses.tss-yonder.com laborator1
# Listarea fisierelor din directorul curent, inclusiv cele ascunse
$> ls -la
total 0
drwxr-xr-x 5 gpaiu staff 160 Feb 12 17:29 .
drwxr-xr-x 18 gpaiu staff 576 Jan 31 10:28 ..
-rw-r--r-- 1 gpaiu staff 0 Feb 12 17:29 .fisier_ascuns
drwxr-xr-x 23 gpaiu staff 736 Jan 24 15:48 courses.tss-yonder.com
drwxr-xr-x 5 gpaiu staff 160 Feb 12 17:26 laborator1
# Afisarea directorului curent, in forma de lista detaliata, fara a lista fisierele
$> ls -ld $(pwd)
drwxr-xr-x 4 gpaiu staff 128 Feb 12 17:26 /Users/gpaiu/Documents/Work/MLMOS
# Afisarea fisierelor, cu omiterea . si .., cate unul pe linie
$> ls -1A
.fisier_ascuns
courses.tss-yonder.com
laborator1
$> pwd
/Users/gpaiu/Documents/Work/MLMOS
$> cd .. && pwd
/Users/gpaiu/Documents/Work
$> cd /Users/gpaiu/Documents && pwd
/Users/gpaiu/Documents
$> cd && pwd
/Users/gpaiu
$> cd . && pwd
/Users/gpaiu
$> cp stdout.log stdout.log.backup
$> ls stdout*
stdout.log stdout.log.backup
# Sterge fisierul creat precedent
$> rm -f stdout.log.backup
$> mv stdout.log stdout.log.backup
$> ls stdout*
stdout.log.backup
$> mkdir logs
$> mv stdout.log.backup logs
$> ls logs
stdout.log
# Cauta aparitia sirului de caractere intr-un fisier
$> grep root /etc/passwd
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false
# Poate fi folosit impreuna cu named pipe
$> cat /etc/passwd | grep root
# Case insensitive
$> grep -i administrator /etc/passwd
root:*:0:0:System Administrator:/var/root:/bin/sh
_cyrus:*:77:6:Cyrus Administrator:/var/imap:/usr/bin/false
_dovecot:*:214:6:Dovecot Administrator:/var/empty:/usr/bin/false
# Suport pentru expresii regulate
$> grep -i "^root:" /etc/passwd
root:*:0:0:System Administrator:/var/root:/bin/sh
# Afiseaza continutul unui fisier
$> cat fisier.txt
Primul laborator
$> for i in $(seq 1 10); do echo "Linia $i" >> lista.txt; done
$> cat lista.txt
Linia 1
Linia 2
Linia 3
Linia 4
Linia 5
Linia 6
Linia 7
Linia 8
Linia 9
Linia 10
$> head -5 lista.txt
Linia 1
Linia 2
Linia 3
Linia 4
Linia 5
$> tail -3 lista.txt
Linia 8
Linia 9
Linia 10
$> head -7 lista.txt | tail -1
Linia 7
Program Bash care preia doua argumente, le valideaza sa fie numere intregi si le adauga, printand suma. Programul ilustreaza urmatoarele concepte:
#!/bin/bash
este_intreg() {
local arg=$1
[[ $arg =~ ^-?[0-9]+$ ]] && return 0
return 1
}
argument_valid() {
local arg=$1
if [[ "$arg" ]] && este_intreg $arg; then
return 0
fi
echo "Argumentul $arg nu este valid"
return 1
}
adauga() {
local arg1=$1
local arg2=$2
if argument_valid $arg1 && argument_valid $arg2; then
sum=$(($arg1+$arg2))
echo $sum
return 0
fi
return 1
}
usage() {
echo "$(basename $0) ARGUMENT1 ARGUMENT2"
}
if [[ $# -ne 2 ]]; then
usage
exit 1
else
adauga $1 $2
fi