Un shell este interpretorul de comenzi pentru sistemul de operare. Bash este shell-ul meu preferat, dar fiecare shell Linux interpretează comenzile tastate de utilizator sau sysadmin într-o formă pe care sistemul de operare o poate folosi. Când rezultatele sunt returnate către programul shell, acesta le trimite la STDOUT care, în mod implicit, le afișează în terminal. Toate shell-urile cu care sunt familiarizat sunt, de asemenea, limbaje de programare.

Funcționalități precum completarea tabulatoarelor, rechemarea și editarea liniei de comandă și scurtături precum aliasurile, toate contribuie la valoarea sa ca un shell puternic. Modul său implicit de editare a liniei de comandă folosește Emacs, dar una dintre caracteristicile mele preferate ale lui Bash este că îl pot schimba în modul Vi pentru a folosi comenzi de editare care fac deja parte din memoria mea musculară.

Cu toate acestea, dacă vă gândiți la Bash doar ca la un shell, pierdeți o mare parte din adevărata sa putere. În timp ce făceam cercetări pentru cursul meu de autoinstruire Linux în trei volume (pe care se bazează această serie de articole), am aflat lucruri despre Bash pe care nu le știam în cei peste 20 de ani de lucru cu Linux. Unele dintre aceste noi cunoștințe se referă la utilizarea sa ca limbaj de programare. Bash este un limbaj de programare puternic, unul perfect conceput pentru a fi utilizat în linia de comandă și în scripturile shell.

Această serie de trei părți explorează utilizarea Bash ca limbaj de programare pentru interfața liniei de comandă (CLI). Acest prim articol analizează o programare simplă în linie de comandă cu Bash, variabile și operatori de control. Celelalte articole explorează tipurile de fișiere Bash; operatorii logici de șiruri de caractere, numerici și diverși operatori logici care oferă o logică de control al fluxului de execuție; diferite tipuri de expansiuni de shell; și buclele for, while și until care permit efectuarea de operații repetitive. De asemenea, vor fi analizate unele comenzi care simplifică și susțin utilizarea acestor instrumente.

Shell-ul

Un shell este interpretorul de comenzi pentru sistemul de operare. Bash este shell-ul meu preferat, dar fiecare shell Linux interpretează comenzile tastate de utilizator sau sysadmin într-o formă pe care sistemul de operare o poate folosi. Când rezultatele sunt returnate către programul shell, acesta le afișează în terminal. Toate shell-urile cu care sunt familiarizat sunt, de asemenea, limbaje de programare.

Bash este acronimul de la Bourne Again Shell, deoarece shell-ul Bash se bazează pe vechiul shell Bourne care a fost scris de Steven Bourne în 1977. Sunt disponibile multe alte shell-uri, dar acestea sunt cele patru pe care le întâlnesc cel mai frecvent:

  • csh: Shell-ul C pentru programatorii cărora le place sintaxa limbajului C
  • ksh: Shell-ul Korn, scris de David Korn și popular printre utilizatorii Unix
  • tcsh: O versiune a csh cu mai multe caracteristici de ușurință în utilizare
  • zsh: Shell-ul Z, care combină multe caracteristici ale altor shell-uri populare

Toate shell-urile au comenzi încorporate care le completează sau le înlocuiesc pe cele furnizate de utilitarele de bază. Deschideți pagina de manual a shell-ului și găsiți secțiunea „BUILT-INS” pentru a vedea comenzile pe care le oferă.

Care shell are propria personalitate și sintaxă. Unele vor funcționa mai bine pentru dumneavoastră decât altele. Eu am folosit shell-ul C, shell-ul Korn și shell-ul Z. Încă îmi place shell-ul Bash mai mult decât oricare dintre ele. Folosiți-l pe cel care funcționează cel mai bine pentru dumneavoastră, deși acest lucru ar putea necesita să încercați unele dintre celelalte. Din fericire, este destul de ușor să schimbați shell-urile.

Toate aceste shell-uri sunt limbaje de programare, precum și interpretoare de comenzi. Iată un tur rapid al unor construcții și instrumente de programare care fac parte integrantă din Bash.

Bash ca limbaj de programare

Majoritatea administratorilor de sistem au folosit Bash pentru a emite comenzi care sunt de obicei destul de simple și directe. Dar Bash poate merge dincolo de introducerea unor comenzi unice, iar mulți administratori de sistem creează programe simple de linie de comandă pentru a efectua o serie de sarcini. Aceste programe sunt instrumente comune care pot economisi timp și efort.

Obiectivul meu atunci când scriu programe CLI este de a economisi timp și efort (adică de a fi sysadminul leneș). Programele CLI sprijină acest lucru prin enumerarea mai multor comenzi într-o anumită secvență care se execută una după alta, astfel încât nu trebuie să urmăriți progresul unei comenzi și să tastați următoarea comandă atunci când prima se termină. Puteți merge să faceți alte lucruri și nu trebuie să monitorizați continuu progresul fiecărei comenzi.

Ce este „un program”?

The Free On-line Dictionary of Computing (FOLDOC) definește un program ca fiind: „Instrucțiunile executate de un calculator, spre deosebire de dispozitivul fizic pe care se execută”. WordNet al Universității Princeton definește un program ca fiind:: „…o secvență de instrucțiuni pe care un calculator le poate interpreta și executa…”. Wikipedia are, de asemenea, o intrare bună despre programele de calculator.

Prin urmare, un program poate consta din una sau mai multe instrucțiuni care execută o sarcină specifică, legată între ele. O instrucțiune de program de calculator se mai numește și instrucțiune de program. Pentru administratorii de sistem, un program este, de obicei, o secvență de comenzi shell. Toate shell-urile disponibile pentru Linux, cel puțin cele cu care sunt eu familiarizat, au cel puțin o formă de bază de capacitate de programare, iar Bash, shell-ul implicit pentru majoritatea distribuțiilor Linux, nu face excepție.

În timp ce această serie folosește Bash (deoarece este atât de omniprezent), dacă folosiți un alt shell, conceptele generale de programare vor fi aceleași, deși construcțiile și sintaxa pot fi oarecum diferite. Unele shell-uri pot suporta anumite caracteristici pe care altele nu le suportă, dar toate oferă o anumită capacitate de programare. Programele de shell pot fi stocate într-un fișier pentru utilizare repetată sau pot fi create în linia de comandă în funcție de necesități.

Programe CLI simple

Cele mai simple programe de linie de comandă sunt una sau două instrucțiuni de program consecutive, care pot fi sau nu legate între ele, care sunt introduse în linia de comandă înainte de a fi apăsată tasta Enter. A doua declarație dintr-un program, dacă există una, ar putea fi dependentă de acțiunile primei, dar nu este necesar să fie.

Există, de asemenea, un element de punctuație sintactică care trebuie precizat în mod clar. Atunci când se introduce o singură comandă pe linia de comandă, apăsarea tastei Enter termină comanda cu un punct și virgulă implicit (;). Atunci când se utilizează într-un program CLI shell introdus ca un singur rând pe linia de comandă, punctul și virgula trebuie să fie folosit pentru a termina fiecare instrucțiune și a o separa de următoarea. Ultima instrucțiune dintr-un program CLI shell poate folosi un punct și virgulă explicit sau implicit.

Câteva sintaxe de bază

Exemplele următoare vor clarifica această sintaxă. Acest program este format dintr-o singură comandă cu un terminator explicit:

$ echo "Hello world." ;
Hello world.

Poate că nu pare a fi un program prea mare, dar este primul program pe care îl întâlnesc cu fiecare nou limbaj de programare pe care îl învăț. Sintaxa poate fi puțin diferită pentru fiecare limbaj în parte, dar rezultatul este același.

Să dezvoltăm puțin acest program banal, dar omniprezent. Rezultatele dvs. vor fi diferite de ale mele pentru că eu am făcut alte experimente, în timp ce dvs. s-ar putea să aveți doar directoarele și fișierele implicite care sunt create în directorul principal al contului la prima conectare la un cont prin intermediul desktop-ului GUI.

$ echo "My home directory." ; ls ;
My home directory.
chapter25 TestFile1.Linux dmesg2.txt Downloads newfile.txt softlink1 testdir6
chapter26 TestFile1.mac dmesg3.txt file005 Pictures Templates testdir
TestFile1 Desktop dmesg.txt link3 Public testdir Videos
TestFile1.dos dmesg1.txt Documents Music random.txt testdir1

Acesta are un pic mai mult sens. Rezultatele sunt legate, dar declarațiile individuale ale programului sunt independente una de cealaltă. Observați că îmi place să pun spații înainte și după punct și virgulă, deoarece face codul un pic mai ușor de citit. Încercați din nou acel mic program CLI fără un punct și virgulă explicit la sfârșit:

$ echo "My home directory." ; ls 

Nu există nicio diferență în rezultat.

Ceva despre variabile

Ca toate limbajele de programare, shell-ul Bash poate face față variabilelor. O variabilă este un nume simbolic care se referă la o anumită locație din memorie care conține o valoare de un anumit fel. Valoarea unei variabile este schimbabilă, adică este variabilă.

Bash nu tastează variabilele ca C și limbajele înrudite, definindu-le ca numere întregi, puncte flotante sau tipuri de șiruri de caractere. În Bash, toate variabilele sunt șiruri de caractere. Un șir de caractere care este un întreg poate fi utilizat în aritmetica numerelor întregi, care este singurul tip de matematică pe care Bash este capabil să o facă. Dacă este necesară o matematică mai complexă, comanda bc poate fi utilizată în programele și scripturile CLI.

Variabilele primesc valori și pot fi utilizate pentru a se referi la aceste valori în programele și scripturile CLI. Valoarea unei variabile se stabilește folosind numele acesteia, dar nu este precedată de semnul $. Atribuirea VAR=10 stabilește valoarea variabilei VAR la 10. Pentru a imprima valoarea variabilei, puteți utiliza instrucțiunea echo $VAR. Începeți cu variabile text (adică nenumerice).

Variabilele Bash devin parte a mediului shell până când sunt dezactivate.

Verificați valoarea inițială a unei variabile care nu a fost atribuită; ar trebui să fie nulă. Apoi, atribuiți o valoare variabilei și imprimați-o pentru a-i verifica valoarea. Puteți face toate acestea într-un singur program CLI:

$ echo $MyVar ; MyVar="Hello World" ; echo $MyVar ;
Hello World
$

Nota: Sintaxa de atribuire a variabilelor este foarte strictă. Nu trebuie să existe spații de o parte și de alta a semnului egal (=) în instrucțiunea de atribuire.

Linia goală indică faptul că valoarea inițială a lui MyVar este nulă. Modificarea și setarea valorii unei variabile se fac în același mod. Acest exemplu arată atât valoarea inițială, cât și cea nouă.

După cum am menționat, Bash poate efectua calcule aritmetice cu numere întregi, ceea ce este util pentru a calcula o referință la locația unui element dintr-o matrice sau pentru a face probleme matematice simple. Nu este potrivit pentru calculul științific sau pentru orice lucru care necesită zecimale, cum ar fi calculele financiare. Există instrumente mult mai bune pentru aceste tipuri de calcule.

Iată un calcul simplu:

$ Var1="7" ; Var2="9" ; echo "Result = $((Var1*Var2))"
Result = 63

Ce se întâmplă atunci când efectuați o operație matematică ce are ca rezultat un număr în virgulă mobilă?

Rezultatul este cel mai apropiat număr întreg. Observați că calculul a fost efectuat ca parte a instrucțiunii echo. Calculul matematic este efectuat înaintea comenzii echo care îl cuprinde, datorită ordinii de precedență Bash. Pentru detalii, consultați pagina de manual Bash și căutați „precedence.”

Operatori de control

Operatorii de control din shell sunt unul dintre operatorii sintactici pentru crearea cu ușurință a unor programe interesante în linie de comandă. Cea mai simplă formă de program CLI este doar înșiruirea mai multor comenzi împreună într-o secvență pe linia de comandă:

command1 ; command2 ; command3 ; command4 ; . . . ; etc. ;

Aceste comenzi se execută toate fără probleme atâta timp cât nu apar erori. Dar ce se întâmplă atunci când apare o eroare? Puteți să anticipați și să permiteți erorile folosind operatorii de control încorporați && și ||| Bash. Acești doi operatori de control oferă un anumit control al fluxului și vă permit să modificați secvența de execuție a codului. Punctul și virgula este, de asemenea, considerat a fi un operator de control Bash, la fel ca și caracterul newline.

Operatorul && spune pur și simplu: „dacă comanda1 are succes, atunci executați comanda2. Dacă comanda1 eșuează din orice motiv, atunci comanda2 este sărită.” Această sintaxă arată astfel:

command1 && command2

Acum, uitați-vă la câteva comenzi care vor crea un nou director și – dacă are succes – îl vor transforma în directorul de lucru actual (PWD). Asigurați-vă că directorul dvs. personal (~) este PWD. Încercați mai întâi acest lucru în /root, un director la care nu aveți acces:

Eroarea a fost emisă de comanda mkdir. Nu ați primit o eroare care să indice că fișierul nu a putut fi creat deoarece crearea directorului a eșuat. Operatorul de control && a sesizat codul de returnare diferit de zero, astfel încât comanda touch a fost sărită. Utilizarea operatorului de control && împiedică rularea comenzii touch pentru că a existat o eroare la crearea directorului. Acest tip de control al fluxului programului de linie de comandă poate împiedica erorile să se complice și să facă o adevărată mizerie. Dar este timpul să devenim puțin mai complicați.

Operatorul de control || vă permite să adăugați o altă instrucțiune de program care se execută atunci când instrucțiunea de program inițială returnează un cod mai mare decât zero. Sintaxa de bază arată astfel:

command1 || command2 

Această sintaxă sună astfel: „Dacă comanda1 eșuează, executați comanda2”. Aceasta implică faptul că, dacă comanda1 reușește, comanda2 este sărită. Încercați acest lucru încercând să creați un nou director:

Este exact ceea ce v-ați aștepta. Deoarece noul director nu a putut fi creat, prima comandă a eșuat, ceea ce a dus la executarea celei de-a doua comenzi.

Combinarea acestor doi operatori oferă ce este mai bun din ambele. Sintaxa operatorului de control care utilizează un anumit control al fluxului ia această formă generală atunci când sunt utilizați operatorii de control && și |||:

preceding commands ; command1 && command2 || command3 ; following commands

Această sintaxă poate fi enunțată astfel: „Dacă comanda1 iese cu un cod de întoarcere 0, atunci se execută comanda2, altfel se execută comanda3.” Încercați:

Încercați acum ultima comandă din nou folosind directorul dvs. personal în loc de directorul /root. Veți avea permisiunea de a crea acest director:

$ Dir=~/testdir ; mkdir $Dir && cd $Dir || echo "$Dir was not created."
$

Sintaxa operatorului de control, cum ar fi comanda1 &&comanda2, funcționează deoarece fiecare comandă trimite un cod de întoarcere (RC) către shell care indică dacă s-a finalizat cu succes sau dacă a existat un anumit tip de eșec în timpul execuției. Prin convenție, un RC de zero (0) indică succesul, iar orice număr pozitiv indică un anumit tip de eșec. Unele dintre instrumentele pe care le folosesc administratorii de sistem returnează doar un unu (1) pentru a indica un eșec, dar multe folosesc alte coduri pentru a indica tipul de eșec care a avut loc.

Variabila shell Bash $? conține RC-ul de la ultima comandă. Acest RC poate fi verificat foarte ușor de un script, de următoarea comandă dintr-o listă de comenzi sau chiar direct de către administratorul de sistem. Începeți prin a rula o comandă simplă și verificați imediat RC. RC va fi întotdeauna pentru ultima comandă care a fost executată înainte de a vă uita la ea.

În acest caz, RC este zero, ceea ce înseamnă că comanda s-a finalizat cu succes. Acum, încercați aceeași comandă pe directorul home al lui root, un director pentru care nu aveți permisiuni:

În acest caz, RC este doi; aceasta înseamnă că a fost refuzată permisiunea unui utilizator non-root de a accesa un director la care utilizatorul nu are acces permis. Operatorii de control folosesc aceste RC-uri pentru a vă permite să modificați secvența de execuție a programului.

Rezumat

Acest articol a analizat Bash ca limbaj de programare și a explorat sintaxa de bază a acestuia, precum și câteva instrumente de bază. Acesta a arătat cum se tipăresc date pe STDOUT și cum se utilizează variabilele și operatorii de control. Următorul articol din această serie analizează unii dintre numeroșii operatori logici Bash care controlează fluxul de execuție a instrucțiunilor.

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.