Essentials Pagina 8

De la Wiki Linux Advanced
Sari la navigare Sari la căutare

Laborator 8

Shell Scripts

1.1 Introducere in Bash

Shellul este interpretorul de comenzi. Acesta parseaza comenzile introduse de utilizator, le verifica din punct de vedere al sintaxei si le trimite kernel-ului spre executie.

Exista mai multe shelluri (Bourne, C Shell, recent aparute Zsh si Fish, etc), dar default pe Linux este shellul numit Bash (Bourne Again Shell). Fizic Bash-ul este reprezentat de fisierul /bin/bash

Pe langa interpretarea si executia comenzilor, Bash-ul ofera si alte facilitati printre care: editarea liniei de comanda, history, alias-uri, dar si un limbaj de programare structurat propriu.

Un script de shell este un fisier text (ASCII) care contine comenzi de shell organizate intr-un mod logic. Pe langa comenzi, script-ul mai contine si variabile (locale sau globale), parametri pozitionali precum si structuri de programare specifice (if..then..else, while, do, until, for, case, selsect etc). Un script este folosit pentru a imbina comenzi si diverse structuri de control pentru a oferi o noua functionalitate sau a automatiza task-uri.

Etapele crearii unui script sunt:

a) crearea unui fisier text folosind editorul preferat (Exemplu: vim) b) editarea fisierului pentru a contine functionalitatea dorita c) testarea scriptului adica executia/rularea acestuia

Modul de executie a unui script numit script1:

1. Din directorul care contine scriptul se ruleaza : ./script1 Fisierul script1 trebuie sa aiba dreptul de executie. Fiindca directorul curent (.) nu se afla in $PATH (altfel grave probleme de securitate), scriptul trebuie sa fie executat cu calea absoluta sau cu ./nume_script In acest caz se porneste un shell nou ca sub proces al shellului curent in care se executa comenzile din script.

2. Din directorul care contine fisierul script1 se ruleaza: . script1 sau source script1. Se executa comenzile din script1 in shell-ul curent. Fisierul script1 nu trebuie sa aiba dreptul de executie. Una dintre diferentele dintre prima si a doua varianta este ca variabilele exportate sau globale sunt vizibile in shell-ul curent in varianta a doua, dar nu si in prima varianta.

Nota Varianta cea mai folosita de executie a unui script este prima: ./script Un script trebuie sa contina pe prima linie o referire la programul cu care se executa (Bash, Perl, PHP, Python etc). Astfel prima linie a unui script Bash este invariabil: #!/bin/bash. In interiorul scriptului #(diez) reprezinta un comentariu. Exceptie face prima linie.

echo se foloseste pentru afisa un string (sir de caractere) sau o variabila la consola. Exemplu: echo "Linux"

Exemplu

1. Script care afiseaza mesajul: Acesta este primul exemplu !

#!/bin/bash echo "Acesta este primul exemplu !"

2. Script care creaza un fiser numit continut_etc.txt in directorul curent ce contine fisierele si directoarele din directorul /etc, iar apoi afiseaza spatiul total, ocupat si liber de pe fiecare partitie de pe Hard Disk.

#!/bin/bash ls -l /etc > continut_etc.txt
echo "Fisierul continut_etc.txt a fost creat in directorul curent!"
echo "Informatii partitii:"
df -h Important

O cunoastere acceptabila a modului de creare de scripturi este esentiala pentru orice Administrator de sistem. In cazul persoanelor incepatoare care nu au experienta in programare (orice limbaj) procesul de scripting pare la prima vedere extrem de complicat.

Este nevoie de multe exercitii si exemple pentru o intelegere aprofundata. Intotdeauna se incepe cu exercitii simple si anume scripturi formate din cateva randuri.

1.2 Variabile, constante si functii

Prezentare generala: 1. O variabila reprezinta un nume pentru o locatie de memorie unde se gaseste o valoare. Se obisnuieste (nu este obligatoriu) ca variabilele sa se scrie cu litera mare.

2. Comparativ cu alte limbaje de programare (C/C++, JAVA) variabilele in Bash nu au tip. Ele sunt string-uri, dar in functie de context pot fi evaluate ca intreg, double etc.

3. O variabila se declara: NUME_VAR=valoare

Important Nu se foloseste spatiu intre NUME_VAR si valoare. i = 1 reprezinta eroare. Sintaxa bash - ului este extrem de stricta. Un spatiu in plus sau in minus reprezinta o eroare fatala.

Exemplu:

NUME="dan"
varsta=20

4. Pentru a ne referi la continutul unei varibile se foloseste semnul $ (dollar) in fata numelui variabilei. Exemplu: echo $varsta

5. Variabilele pot fi locale sau globale. Cele locale sunt vizibile doar in shell-ul curent, iar cele globale sunt vizibile in shell-ul curent si in toate subprocesele shell-ului curent. Astfel in interiorul unui script daca se foloseste o variabila globala aceasta va fi accesibila oricarei comenzi/program lansata din acel script. Variabilele globale nu sunt accesibile parintelui unui proces, adica shell-ului de unde s-a executat scriptul. Exceptie face varianta 2 de executie a unui script adica folosind source nume_script

6. Pentru a declara o variabila globala aceasta trebuie exportata. Se foloseste cuvantul cheie export

Exemplu: export VARSTA=20
variabilele globale se numesc de environment;
pentru a vizualiza variabilele locale se foloseste comanda set;
pentru a vizualiza variabilele globale se foloseste comanda env;
pentru sterge o variabila se foloseste comanda unset NUME_VAR;

Exemplu de varibile globale predefinite:

PATH -> contine o lista de directoare in care shell-ul cauta comanda care se executa.

Pentru a concatena un string la variabila PATH se foloseste caracterul : (doua puncte).

Exemplu

Daca dorim sa adaugam directorul /home/dan/scripts in PATH: export

PATH=PATH:/home/stud/scripts

Dupa aceasta scripturi si comenzi din /home/stud/scripts pot fi rulate in orice director ne am afla doar prin numele lor. Altfel trebuie folosita calea absoluta sau aflandu-ne in director se executa: ./nume_comanda

HOSTNAME -> contine hostname-ul calculatorului
SHELL -> contine shell-ul default
HISTSIZE - contine nr. de comenzi care vor fi memorate in history
USER -> contine EUID
PWD -> contine directorul curent
OLDPWD -> contine directorul precedent si se foloseste de comanda: cd –
HOME -> contine home directory al EUID
RANDOM -> variabila al carei continut este pseudoaleator
TMOUT -> nr in secunde dupa care se face logout automat daca nu se executa nicio comanda

7. Diferenta dintre ghilimele simple(apostrof) si ghilimele duble este aceea ca ghilimele simple nu interpreteaza $ ca si caracter special. In interiorul ghilimelelor simple fiecare caracter special cu exceptia ' (ghilimea simpla) este interpretat literal.

Exemplu

varsta=20 echo "$varsta" ##se afiseaza 20 echo '$varsta' ##se afiseaza $varsta

8. O variabila poate fi declarata read-only sau de tip array. O variabila read-only se mai numeste si constanta.

Exemplu

1. var1 este readonly. Aceasta nu poate fi modificata sau stearsa folosind unset.
declare -r var1=7
2. Pentru a declara un array/vector:
ARRAY=(unu doi trei) echo ${ARRAY[*]} echo ${ARRAY[1]} i=2 echo
${ARRAY[]} unset ARRAY[1] unset ARRAY
ARRAY nu este cuvant cheie. In loc de ARRAY poate fi orice cuvant.

9. Pentru a citi o variabila de la tastatura se foloseste cuvantul cheie read Exemplu:

#!/bin/bash echo "Introdu nume fisier:" read FILE echo "Fisierul introdus este $FILE"

10. In bash exista caractere speciale care sunt interpretate in mod deosebit.

Exemple: $ (dollar), "(ghilimea dubla) sau \ (backslash). Pentru a anula efectul special al

caracterului, acesta se precede cu \ (backslash).

Exemplu: echo \$var -> Afiseaza $var. $ nu mai este caracter special.

1.3 Parametri pozitionali

Bash-ul foloseste parametri speciali la care ne putem referi in interiorul unui script pentru a avea acces la anumite valori. Acesti parametri speciali se pot folosi ca si variabilele, doar ca exista default si nu trebuie creati. Continutul acestora este de asemenea standard.

Acestia sunt:

1. $0 - contine numele scriptului Scriptul poate actiona diferit in functie de numele cu care a fost rulat ( Exemplu: daca se ruleaza folosind un simlink al scriptului. Vezi comanda /bin/egrep care este un simlink catre /bin/grep dar are totusi functionalitate diferita).

2. $1 - reprezinta primul argument al scriptului, $2 al doilea argument al scriptului etc. Incepand cu argumentul 10 acesta trebuie incadrat intre acolade ${10}, ${11} etc. Se folosesc pentru a evita erori in momentul in care scriptul este rulat fara argumente sau cu un alt nr. de argumente (iar acesta asteapta sa primeasca argumente).

3. $? - reprezinta statusul ultimei comenzi executate. In Bash Zero este statusul pentru non-error iar diferit de zero este statusul pentru eroare. Orice comanda/program are un status de exit, zero sau non-zero. Se foloseste pentru a continua executia scriptului (sau a modifica comportamentul acestuia) in functie de statusul comenzilor anterioare.

4. $# - reprezinta nr. de argumente ale scriptului Se poate lua o decizie in functie de nr. de argumente cu care a fost rulat scriptul.

5. $* - reprezinta toate argumentele date scriptului.

6. $$ - reprezinta PID shell. Astel in functie de cum rulam scriptul $$ are alta valoare:source f1 - $$ reprezinta PID bash (shell curent) ./f1 - $$ reprezinta PID noului sub-shell creat in care se executa comenzile

7. $! - reprezinta PID ultimului proces executat in background.

Exemplu 1. Script care sterge fisierul sau directorul pe care-l primeste ca argument

#!/bin/bash rm -rf $1

2. Afisarea numelui scriptului

#!/bin/bash Echo "Numele scriptului executat este: $0"

1.4 Alte facilitati Bash

Alias

Un alias reprezinta un mod prin care o comanda sau o serie de comenzi se executa folosind un alt nume. Pentru a crea un alias se foloseste comanda: alias comanda_noua='comanda_substituita'

Exemplu 1. alias copy='cp' 2. alias search='grep' 3. alias ls='ls -F' 4. alias rm='rm -i' 5. alias ll='ls -l' 6. alias stop='kill -9'

Daca aliasul este compus din mai multe cuvinte acestea trebuie incadrate intre ghilimele simple (apostrof).Pentru a vizualiza toate aliasurile din sistem se foloseste comanda alias fara nici un argument.Pentru a executa comanda originala in locul aliasului se foloseste \ (backslash) urmat de comanda.

Example: \ls Pentru a sterge un alias se foloseste comanda unalias Exemplu: unalias ls

Nota Un alias exista doar in shell-ul curent (nu exista nici macar in subshell-urile shell-ului curent).

Customizare Environment

Prompting variables (prompt strings)

Bash foloseste 4 variabile speciale numite "prompt strings": PS1, PS2, PS3 si PS4. 1. PS1 este numit "primary prompt string" si reprezinta prompterul curent. De cele mai multe ori acesta se modifica pentru a arata informatii cat mai utile despre sesiunea curenta.

PS1 foloseste niste macro-uri care se expandeaza cu un anumit continut astfel:
\A - current time in HH:MM hours format
\d - current date
\@ - the current time in 12 hours format
\H - the hostname
\h - the hostname up to the first dot (.)
\s - the name of the shell
\u - username of the EUID
\w - the current working directory
\W - the current working directory (basename) - relativ
\$ - if EUID==0 print # else print $


Nota Un exemplu excelent de modificare PS1 este: export PS1='[\u@\h \w]$' Avand acest prompter adminul are intotdeauna informatii despre userul cu care s-a conectat, host-ul pe care este conectat precum si calea absoluta a directorului curent. Linia de mai sus se adauga in fisierul de customizare ~/.bashrc

2. PS2 este numit "secondary prompt string" si are valoarea default > (mai mare). Se foloseste atunci cand se scrie o comanda incompleta si se apasa ENTER.

3. PS3 se numeste "prompt string for the select command" si se foloseste in scripting impreuna cu comanda select

4. PS4 se numeste "prompt string for the xtrace option" si reprezinta un prompt string folosit in debugging si flow control.

Environment

Fiecare utilizator are propriul mediu de lucru numit si Environment. Customizarea Environmentului presupune modificarea unor variabile si parametri astfel incat mediul de lucru sa fie cat mai prietenos si sa ne ofere cat mai multe informatii. Din mediul de lucru al unui utilizator fac parte: aliasurile sale, umask, modul de afisare al prompterului, variabila PATH in care shellul cauta comenzile, ulimit etc

Exista fisiere de initializare pentru fiecare user care sunt citite de shell la fiecare pornire a acestuia:

~/.bashrc - este primul fisier citit de shell la login. In acest fisier trebuie declarate variabile, alias-uri etc pentru fiecare user. ~/.bash_profile - este citit dupa ~/.bashrc ~/.bash_logout - este citit de shell inainte de logout. In acest fisier se pot reseta variabile, sterge fisiere temporare sau alte functii care vrem sa aiba loc inainte de logout.


Fisierul /etc/profile este un alt fisier de customizare "system-wide". Acesta nu apartine unui anumit user, iar in el se configureaza mediul pentru toti userii. Il folosim de exemplu daca dorim setarea unui alias pentru toti userii din sistem. Aceste fisiere nu sunt recitite automat de shell dupa modificare. Toate configurarile au efect dupa o noua logare in cazul ~/.bashrc sau ~/.bash_profile sau dupa o restartare a sistemului in cazul /etc/profile.Pentru a forta recitirea lor se foloseste comanda source sau . (dot) urmata de nume fisier. source sau . executa comenzile din interiorul fisierului in shellul curent.

Exemplu: source ~/.bashrc sau . ~/.bashrc Daca ~/.bash_profile nu exista shell-ul cauta ~/.bash_login. Daca nici aceasta nu exista cauta ~/.profile. In aceste fisiere speciale de initializare se seteaza: PS1, TMOUT, PATH, alias, umask etc pentru fiecare utilizator

Nota Fisierele de initializare pentru fiecare utilizator se gasesc in home directory al acestuia (~) si sunt ascunse fiindca incep cu .(punct). Pentru vizualizarea lor se foloseste comanda ls cu optiunea -a Exemplu: ls -la ~

Nota In functie de distributia de Linux numele si ordinea de citire a fisierelor de customizare a mediului de lucru pentru fiecare user poate sa difere. Totusi, pe marea majoritate a distributiilor de Linux (RedHat, Fedora, CentOS, Suse, Ubuntu, Kubuntu, Debian) exista ~/.bashrc. In acest caz se recomanda folosirea doar a acestuia

Exemplu ~/.bashrc:

# User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias cauta=find alias muta=mv alias S='ssh -l root -p 7890 ssh.crystalmind.ro' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi export PS1='[\u@\h \w]$' export
PATH=:/home/dan/scripts umask=0022


1.5 Flow Control

Conditii de testare

Nota Informatiile din acesta pagina au scopul de referinta pentru testele folosite de structurile de control ce urmeaza a fi prezentate. Ele nu trebuie invatate la acest moment in afara conextului de flow control ci doar impreuna cu structurile if..then..else, while, case etc

Structurile de control (if..then..else, while etc) presupun conditii de testare.

Acestea sunt:

1. Pentru fisiere
-e = fisierul exista
-f = fisierul exista si este de tipul regular file
Exemplu: -f $FILE
-s = fisierul nu are dimensiunea zero
-d = fisierul exista si este de tip director
-c = fisierul exista si este de tip char device
-b = fisierul exista si este de tip block device
-r = fisierul exista si are permisiunea read
-w = fisierul exista si are permisiunea write
-x = fisierul exista si are permisiunea execute
-g = fisierul are GUID setat
-u = fisierul are SUID setat
-k = fisierul are sticky bit setat
-nt = fisierul este mai nou decat un alt fisier
Exemplu: file1 -nt file = file1 is newer than file2
! -> inverseaza sensul (neaga)

2. Pentru comparatie

-eq = equal to
-ne = not equal to
-gt = greater than
Exemplu: $i -gt -$j
-ge = greater than or equal
-lt = less than
-le = less than or egal

3. Pentru stringuri (siruri de caractere)

-z = lungimea sirului este zero
-n = lungimea sirului este non-zero
= egal (comparativ cu alte limbaje de programare operatorul de comparatie este un singur egal) != diferit
Exemplu: $str1 != $str2
-a = SI LOGIC (AND)
-o = SAU LOGIC (OR)

Exemplu 1. Testul este adevarat daca ambele conditii sunt adevarate simultan (valoarea variabilei USER este root si valoarea variabilei SHELL este bash)

$USER = "root" -a $SHELL = "bash"

In cazul comparatiei a doua stringuri din punct de vedere al sintaxei bash este obligatoriu un spatiu inainte de = (egal) si un spatiu dupa = (egal).

Exemplu: $USER="root" este gresit, $USER = "root" este corect.

2. Testul este adevarat daca una dintre conditii este adevarata(i mai mic ca 10 SAU i mai mare ca 100) $i -lt 10 -o $i gt 100

Nota Contiditiile de testare prezentate mai sus sunt doar cele mai folosite. Pentru lista completa executati: man test test EXPR sau [ EXPR ] au acelasi rezultat.

If..then..else

Cea mai simpla constructie de flow control este cea conditionala reprezentata de if. In functie de o valoarea de adevar a unei conditii se stabilesc instructiunile ce trebuie executate. Conditiile de test se refera la proprietati ale fisierelor, comparatii numerice sau sunt referitoare la stringuri.

Sintaxa pentru if este:

if [ conditie_de_test ] then lista_de_instructiuni fi

Daca conditia de test este adevarata se executa lista de instructiuni, altfel aceasta nu se executa.

Exemplu 1. Daca primul argument al scriptului este fisier se executa: cat fisier

if [ -f $1 ] then cat $1 fi

2. Daca valoarea variabilei i este 10 se afiseaza mesajul "Variabila i are valoarea 10" if [ $i -eq 10 ] then echo "Variabila i are valoarea 10" fi

Sintaxa pentru if..else este:

if [ conditie_de_test ] then lista_de_instructiuni else lista_de_instructiuni_default fi

Data conditia de test este adevarata se executa lista_de_instructiuni, altfel se executa lista_de_instructiuni_default

Exemplu Daca valoarea variabilei VARSTA citita de la tastatura este mai mica decat 18 se afiseaza mesajul "Esti minor!", altfel se afiseaza mesajul "Esti major!"

#!/bin/bash echo "Introdu varsta:" read VARSTA if [ $VARSTA -lt 18 ] then echo "Esti minor!" else echo "Esti major!" fi

Sintaxa pentru if..elif..else este:

if [ conditie_de_test1 ] then lista_de_instructiuni1 elif [ conditie_de_test2 ] then
lista_de_instructiuni2 elif [ conditie_de_test3 ] then lista_de_instructiuni3 else
lista_de_instructiuni_default fi

Exemplu Daca variabila ORA citita de la tastatura este mai mica decat 12 se afiseaza mesajul "Buna dimineata" daca este intre 12 si 18 se afiseaza mesajul "Buna ziua", daca este intre 18 si 24 se afiseaza "Noapte Buna!". Pentru orice alta situatie se afiseaza mesajul "Eroare!".

#!/bin/bash read i if [ $i -lt 12 ] then echo "Buna dimineata!" elif [ $i -ge 12 -a $i -lt 18 ] then echo "Buna ziua!" elif [ $i -ge 18 -a $i -le 24 ] then echo "Noapte buna !" else echo "Eroare!" fi -a reprezinta SI LOGIC (AND). Testul este adevarat daca ambele conditii sunt adevarate simultan.

-o reprezinta SAU LOGIC (OR). Testul este adevarat daca una dintre contitii este adevarata.

Exemplu 1. Testul este adevarat daca ambele conditii sunt adevarate (primul parametru este fisier si exista SI are permisiunea de read). Ambele conditii sunt adevarate simultan.

if [ -e $1 -a -r ]

2. Testul este adevarat daca primul parametru primit de script este fisier SAU acesta este director. Una dintre conditii este adevarata.

if [ -f $1 -o -d $1 ]

For

For se foloseste pentru a executa o sectiune de cod de un numar repetat de ori (ciclu). Varianta clasica de for din Bash este diferita de cea din alte limbaje de programare. Sintaxa pentru for este: for VAR in lista_de_valori do instructiuni done Se executa instructiunile specificate de atatea ori cate valori avem in lista. Pentru fiecare iteratie variabila VAR ia o valoare din lista_de_valori. Separatorul pentru valorile din lista este default spatiu sau valoarea variabilei globale IFS.

Exemplu 1. Script care exemplifica ciclul de tip for prin trimiterea unui pachet ping la fiecare din cele 3 IP-uri.

Instructiunile dintre do si done se executa de atatea ori cate valori avem in lista (3 valori).

Pentru fiecare ciclu valoarea variabilei IP este o valoare din lista. Valorile din lista sunt separate prin spatiu.

#!/bin/bash for IP in 192.168.0.1 192.168.0.2 192.168.0.3 do ping -c 1 $IP done

2. Exemplu for modificand valoara variabilei IFS care este separatorul valorilor.

#!/bin/bash #Acest script afiseaza fiecare director din $PATH pe cate un rand IFS=: for DIR in $PATH do echo $DIR done

In Bash exista si structura de tip for ca in C/C++. Aceasta este insa mai putin folosita.

Exemplu
for ca in C/C++:
LIMIT=10 for((a=0;a<=$LIMIT;a++)) do echo $a done

While

Structura de tip while se foloseste pentru a executa o serie de instructiuni (cele dintre do si done) atata timp cat conditia de test este adevarata.

while [ conditie_de_test ] do lista_de_instructiuni done

Exemplu while:

#!/bin/bash
#script care afiseaza numerele intre 0 zi 100
LIMIT=100
i=0
while [ $i –le $LIMIT ]
do
echo "i=$i"
let i=i+1
done


Case

Structura de tip case se foloseste pentru a executa o serie de instructiuni in functie de diferite conditii de testare.

Sintaxa pentru case este:

case VARIABILA in
valoare1)
instructiuni1
;;
valoare2)
instructiuni
;;
*)
instructiuni_default
;;
esac
* -> reprezinta instructiunile ce se vor executa default daca variabila nu are niciuna dintre valorile de mai sus.

Exemplu

#!/bin/bash echo "Introdu nr:" read nr case $nr in 1) echo "nr este 1" ;; 2) echo "nr este2" ;; *) echo "nr are alta valoare" ;; esac

Structura de tip case poate fi oricand inlocuita cu o structura de tip if..elif..else

Exemplul de mai sus folosind if..elif..else este:

#!/bin/bash
echo "Introdu nr:"
read nr
if [ $nr -eq 1 ]
then echo "nr este 1"
elif [ $nr -eq 2 ]
then
echo "nr este 2"
else
echo "nr este altceva"
fi

Important

Structura de tip case este foarte importanta si trebuie inteleasa bine. Toate scripturile de initializare a serviciilor (cele din /etc/init.d ) folosesc o structura de tip case.

Structura unui script de initializare din /etc/init.d este:

case $1 in
start) instructiuni de pornire serviciu
;;
stop) instuctiuni de oprire serviciu
;;
restart) instructiuni de restartare serviciu
;;
*) afisare help script 
esac

$1 reprezinta primul parametru al scriptului si poate fi start, stop sau restart.

Exemplu: Pentru restartarea retelei se foloseste: /etc/init.d/network restart, unde network este scriptul de initializare iar restart primul parametru pe care-l primeste.

Exemplu Presupunem ca am compilat si instalat serverul Apache in directorul /opt/apache. Daemonul http se porneste ruland comanda: /opt/apache/bin/apachectl start, se opreste cu /opt/apache/bin/apachectl stop si se restarteaza cu /opt/apache/bin/apachectl restart. Se doreste pornirea serverului la butarea sistemului, mai exact la intrarea in runlevel 3.

Etape: 1. Se creaza un script in /etc/init.d. Numele poate fi ales aleator, in exemplul nostru acesta se numeste init_apache 2. Se creaza un symlink catre /etc/init.d/init_apache in /etc/init.d/rc3.d numit S99Apache. Numele symlinkului este important sa inceapa cu litera S urmata de un umar intre 0 si 99.

La intrarea in runlevel 3 se va rula automat acest script cu parametrul start. Structura scriptului /etc/init.d/init_apache este:

#!/bin/bash
case $1 in
start)
echo "Starting Apache..." /opt/apache/bin/apachectl start echo "OK"
;;
stop) echo "Shutting down Apache..." /opt/apache/bin/apachectl stop echo "OK"
;;
restart) $0 stop $0 start
;;
*) echo "init_apache <start|stop|restart>"
esac

Nota Pentru detalii complete despre modul de pornire a serviciilor la butare cititi capitolul "Managementul Serviciilor" din cursul "Linux Basic Administration" disponibil de asemenea online.

Select

Structura de tip select este specifica doar Bash-ului si se foloseste pentru crearea de meniuri.

Sintaxa acesteia este:

select MENUITEM in menu_list
do
lista_de_comenzi
done

Detalii: - menu_list este lista de meniuri. Valorile din lista sunt separate prin spatiu; - intre do si done sunt instruciunile ce se executa in functie de meniul ales; - intre do si done avem acces la urmatoarele 2 variabile: MENUITEM care contine meniul

selectat si REPLY care se creaza automat si contine inputul userului (ce a scris acesta la consola);

- PS3 contine prompterul de selectare a meniurilor; - userul alege un meniu din lista folosind un nr. de ordine: alege 1 pentru primul meniu, 2 pentru al doilea etc;

Exemplu:

#!/bin/bash
PS3="Alege:"
select ITEM in "Afiseaza continut /etc" "Afiseaza spatiu liber" "Exit"
do
case $REPLY in
1) ls -l /etc
;;
2) df -h
;;
3) exit 0
;;
*) echo "Optiune incorecta"
esac
done

1.6 Substituirea comenzilor

Unei variabile i se poate asigna o valoare in 2 moduri: 1. Folosind NUME_VAR=valoare

Exemplu: EDITOR="VIM"

2. Substituind o comanda cu outputul ei

Exemplu:

VAR=`ls /etc` -> in acest exemplu comanda ls /etc se substituie sau inlocuieste cu outputul ei care se asigneaza variabilei VAR. Variabila VAR va contine outputul comenzii ls -l.

Nota Substituirea unei comenzi cu outputul ei reprezinta unul dintre caracteristicile cele mai puternice ale Bashului, iar majoritatea scripturilor folosesc acest mod de lucru.

Pentru a substitui o comanda cu outputul ei exista 2 variante:

1. Comanda sa incadreza in backquotes ( ``). Atentie, backquotes nu sunt apostroafe sau ghilimele simple.

Exemplu: ME= `whoiam ` -> variabila ME va contine outputul comenzii whoami

2. Comanda se incadreza intre $( si )

Exemplu: ETH0= $(ifconfig eth0) -> variabila numita ETH0 va contine outputul comenzii
ifconfig eth0
Exemplu script ce nu poate fi rulat de catre root
#!/bin/bash
if [ "$(whoami)" = "root" ]
then
echo "Esti root, sorry !"
exit 1;
fi
  1. incep instructiunile ce nu pot fi rulate de catre root"
ls -la ~

Nota

In momentul in care o variabila de tip string este testat folosind un test pentru stringuri este bine ca aceasta sa fie incadrata intre ghilimele duble pentru a forta tipul ei catre string.

Exemplu: VAR="`ifconfig eth0`" if [ -z "$VAR" ] then echo "Interfata eth0 nu exista!" fi

Subshells

Utilizarea subshell-urilor în Bash poate fi avantajoasă din mai multe motive, inclusiv:

1. Izolarea comenzilor: comenzile executate într -un subshell sunt izolate de cochilie părinte. Aceasta înseamnă că orice modificări aduse la variabile, directoare sau alte setări de mediu din subshell nu vor afecta shell-ul părinte.
2. Scoping: Variabilele definite într -un subshell au un domeniu local și nu vor afecta variabile cu același nume în shell-ul părinte.
3. Manevrarea erorilor: subshell -urile pot fi utilizate pentru o mai bună gestionare a erorilor. De exemplu, puteți executa o serie de comenzi într-un subshell și puteți verifica starea de returnare a acesteia fără a afecta fluxul principal al scriptului dvs.

Iată câteva exemple de utilizare a subshell-urilor în Bash:

Schimbarea directorului temporar:

Aceasta schimbă temporar directorul în/calea/în/director, execută comanda LS, apoi se întoarce în directorul original. Schimbarea directorului afectează doar subshell-ul.

-Execuție paralelă:

Aceasta execută mai multe comenzi concomitent în subshell-uri, permițându-le să funcționeze în paralel.

-Manevrarea erorilor:

Aceasta execută comanda1 și comanda2 într -un subshell. Dacă Command1 sau Command2 eșuează (returnează un statut de ieșire non-zero), atunci este ecou „eroare”.

-Setări temporare ale mediului:

Aceasta stabilește o variabilă de mediu temporară la valoare pentru durata comenzii. Odată ce comanda se termină, variabila revine la valoarea sa anterioară (sau este nesetată dacă nu exista înainte).

Subshell-urile sunt versatile și pot fi utilizate creativ pentru a atinge diverse obiective de script, menținând controlul asupra mediului și fluxului de execuție al comenzilor.

In inchiderea cursului Linux Essentials:

La ce pot fi folosite parantezele ( ) in bash?

Utilizari comune

   1. Substitutia comenzii:
       ◦ $(command) or `command`: Executa comanda si ii substituie iesirea.
       ◦ Example: echo $(date) or echo \date``
   2. Expansie aritmetica:
       ◦ (( expression )): Performa operatuni aritmetice si le evalueaza expresia.
       ◦ Example: (( x = 5 + 3 ))
   3. Crearea unui subshell:
       ◦ ( commands ): Execute comenzi intr-un subshell, izolandu-i mediul de cea principala.
       ◦ Example: (cd /path/to/directory && ls)
   4. Declararea unei functii:
       ◦ function_name () { commands; }: Declara o functie.
   5. Gruparea comenzilor:
       ◦ { commands; }: Grupeaza mai multe comenzi impreuna, permitandu-le sa ruleze ca si o singura comanda.
       ◦ Example: { echo "Hello"; echo "World"; }


Pagina anterioară