Bazeleprogramare shell - Articole interesante - Catalog articole - OOO -

Descriere:Linie de comandă, shell de comandă, script de comandă sau script - aceste fraze provoacă reacții ambigue în rândul celor care folosesc computerele într-o măsură sau alta. Utilizatorii Unix cu experiență (inclusiv eu) zâmbesc cu bună știință și dă din cap în semn de aprobare. Cei care au găsit MS-DOS se încruntă de nemulțumire. Generația Windows se uită uluită și ridică din umeri. Cu toate acestea, administratorii Windows experimentați înțeleg ce este în joc, dar nu arată prea mult entuziasm.

Utilizatorii actuali de Linux par să fie conștienți de beneficiile liniei de comandă, dar nu toți (și nu întotdeauna) le folosesc. Motivele sunt diferite. Pe de o parte, există un progres rapid în calitatea și comoditatea interfeței grafice cu utilizatorul în mediile Linux, pe de altă parte, complexitatea și laboriozitatea relativă a lucrului pe linia de comandă. Nu sunt deloc ironic, folosind cuvintele complexitate și laboriozitate - să tastați comenzi lungi pe tastatură nu este chiar atât de ușor. Dar dacă acordați puțin timp și atenție pentru a stăpâni unele dintre metodele de lucru și elementele de bază ale programării shell, atunci rezultatele nu vă vor dezamăgi.

Shell-ul de comandă din orice sisteme de tip Unix, care include GNU/Linux, este un program obișnuit care rulează atât într-o consolă text (care este folosită mai rar), cât și într-un mediu grafic - într-o fereastră de emulator de terminal disponibilă pe orice sistem Linux .

Sarcina sa este simplă și evidentă: să acceptați o linie (sau linii) de intrare, să le analizați și, pe baza rezultatelor acestei analize, să reacționați în consecință - executați o comandă, rulați un program, afișați un mesaj de diagnosticare etc.

Poate apărea întrebarea: de ce să vă deranjațilinie de comandă, dacă există interfețe grafice convenabile și frumoase? Există multe motive pentru aceasta. În primul rând, nu toate operațiunile sunt mai convenabile și mai rapide de efectuat folosind o interfață grafică. În al doilea rând, fiecare program urmează un principiu fundamental al sistemelor Unix: faceți o treabă bine definită și faceți-o bine. Cu alte cuvinte, înțelegeți întotdeauna ce se întâmplă atunci când rulați un anumit utilitar (dacă ceva nu este complet clar, atunci ar trebui să vă referiți la ghidul de om). În al treilea rând, stăpânind comenzile, încercând combinațiile și combinațiile parametrilor acestora, utilizatorul învață sistemul, dobândind o experiență practică valoroasă. Aveți acces la instrumente puternice, cum ar fi conducte la comenzi în lanț pentru procesarea datelor, redirecționarea I/O și puteți programa direct din shell. Poate că merită să ne oprim asupra programării mai detaliat, mai ales că multe scripturi de sistem în Linux (de exemplu, scripturi pentru pornirea serviciilor de sistem) sunt scrise pentru shell.

Deci, shell-ul poate fi considerat ca un limbaj de programare și ca un mediu de rulare software în același timp. Desigur, acest limbaj nu este compilat, ci interpretat. Permite utilizarea variabilelor: sistem sau proprii. Secvența de execuție a comenzilor programului este modificată folosind constructele pentru verificarea stării și alegerea opțiunii corespunzătoare: if-then-else și case. Buclele While, until și for vă permit să automatizați acțiuni repetitive. Este posibil să combinați grupuri de comenzi în blocuri logice. Puteți chiar să scrieți funcții reale cu parametrii trecuți. Astfel, există toate semnele și caracteristicile unui limbaj de programare cu drepturi depline. Să încercăm să extragem din astabeneficiu dublu - împreună cu învățarea elementelor de bază ale programării, ne automatizăm munca zilnică.

Toată lumea știe despre necesitatea de a face backup periodic la date, dar utilizatorii nu au întotdeauna suficient timp pentru această operațiune plictisitoare. Soluția este simplă - organizați backup-uri automate. Aceasta va fi prima noastră sarcină de programare shell.

Orice script de comandă (script - script, deci sunt apelate programele shell) începe cu un șir de identificare, în care interpretorul de comandă este specificat în mod explicit cu calea completă către acesta. Calea completă este o listă secvențială a tuturor directoarelor, începând cu rădăcina, pe care trebuie să le introduceți pentru a ajunge la fișierul țintă și, desigur, numele acestui fișier. Înregistrarea căii complete este extrem de importantă pentru a identifica în mod unic fiecare fișier din ierarhia sistemului de fișiere.

În sfârșit, am ajuns la prima echipă „adevărată”. Vă permite să schimbați directorul (Change Directory), adică mutați din directorul curent în alt director transmis comenzii ca argument. În cele mai multe cazuri, directorul țintă este specificat în mod explicit, de exemplu, cd /tmp sau proiecte cd, dar în cazul nostru, este utilizată variabila de sistem predefinită HOME - conține calea completă către directorul de acasă al utilizatorului curent, pe a cărui scriptul de comandă este în curs de executare. Acest lucru ne scutește de a trebui să facem modificări codului de fiecare dată când utilizatorul se schimbă, deoarece comanda returnează pe oricine în directorul său personal. Semnul dolar „$” în fața numelui unei variabile înseamnă că trebuie să extrageți valoarea conținută în această variabilă și să o înlocuiți pe linia de comandă în loc de numele acesteia. Trebuie remarcat în special faptul că în limbajul de comandă sunt importante shell-urile de litere, adică Acasă,Acasă și casă sunt trei variabile diferite. Prin convenție, literele mari denotă numele variabilelor de sistem: HOME, PATH, EDITOR și așa mai departe. Această convenție nu împiedică utilizatorii să-și pună cu majuscule numele variabilelor, dar de ce să-ți complici viața încălcând normele și regulile general acceptate? De asemenea, nu este recomandat să modificați valorile variabilelor de sistem decât dacă este absolut necesar. În general, respectăm o regulă simplă: folosim variabile de sistem doar pentru citire, iar dacă avem nevoie de ale noastre, atunci îi scriem numele cu litere mici.

Prima noastră comandă ar fi putut fi scrisă mai concis:

' înseamnă, de asemenea, directorul principal al utilizatorului curent. Veteranii din linia de comandă au spus-o și mai succint:

Ideea este că atunci când nu i se oferă niciun argument comenzii cd, aceasta se schimbă în directorul principal.

Următorul pas este construcția clasică de programare de verificare a stării și luarea deciziei corespunzătoare. Schema generală este următoarea:

Ultimul cuvânt al construcției (dacă este în ordine inversă) acționează ca o paranteză de închidere, i.e. limitele listei de comenzi executate atunci când condiția este adevărată. Prezența lui fi este obligatorie, chiar dacă în listă există o singură comandă.

Pentru a testa o condiție, de regulă, se folosește comanda test sau notația sa alternativă între paranteze drepte. Cu alte cuvinte, înregistrări

absolut egal. Prefer parantezele pătrate, deoarece definesc mai clar domeniul de aplicare al condiției testate. Atât parantezele din dreapta cât și cele din stânga trebuie separate de condiție prin spații.

Criteriile de verificare a stării sunt definite de diferite steaguri. Comanda de testare recunoaște o listă foarte mare de ele. În exemplul nostru, indicatorul -d este folosit pentru a verifica dacă este dat dupămarcați numele unui director din viața reală (director). Cele mai frecvent utilizate steaguri atunci când lucrați cu fișiere sunt:

-f - dacă există un fișier obișnuit cu numele dat;

-r - dacă fișierul specificat are dreptul de a citi din el;

-w - dacă fișierul specificat are dreptul de a scrie în el;

-x - dacă fișierul specificat are dreptul de a-l executa;

-s - dacă fișierul specificat are o dimensiune diferită de zero.

În cazul nostru, condiția este precedată de un semn de exclamare, care denotă operația de negație logică, astfel încât sensul condiției care se verifică devine absolut opus. Să încercăm să notăm semnificația acestor comenzi în limba română obișnuită:

În rândul următor, creăm propria noastră variabilă locală cur_date. În marea majoritate a cazurilor, variabilele sunt create prin simpla atribuire a unei anumite valori, de exemplu:

Dar în exemplul nostru, se aplică un mic truc. Vă rugăm să rețineți că după semnul egal - simbolul de atribuire - comanda este scrisă între ghilimele înapoi. Această formă de notație vă permite să atribuiți unei variabile nu șirul în sine, ci rezultatul execuției sale. Iată rezultatul comenzii date, care returnează data și ora curente în formatul specificat de lista de parametri:

%Y este anul curent în formă completă, adică patru cifre (de exemplu, 2009);

%d – numărul zilei curente;

%H este ora curentă în format de 24 de ore;

%M este minutul curent.

Astfel, dacă rulați comanda

Înainte de a începe să creăm un fișier arhivă, trebuie să stabilim ce directoare vom salva în el. Pentru mai multă flexibilitate, puteți specifica un set de directoare care sunt arhivate implicit, dar oferiți posibilitatea de a înlocui acest set cu o listă de directoare transmise ca argument cătrescriptul nostru de comandă. Pentru a face acest lucru, se folosesc variabile shell speciale: $# - numărul de parametri trecuți scriptului și $* - toți parametrii trecuți, scriiți în formatul unei linii.

Verificând condiția „dacă numărul de parametri trecuți este zero”, apoi executați următoarea comandă. Rețineți că cuvântul cheie poate fi scris în linia de condiție, separându-l de expresia condiționată cu punct și virgulă.

Comanda pentru a crea un fișier arhivă și a comprima acest fișier. Utilitarul tar în sine nu comprimă, ci doar colectează toate fișierele și directoarele date într-un singur fișier tar. Primul steag - c (create - create) este destinat pentru aceasta. Comprimarea este efectuată de un program extern - aici este gzip, numit de al doilea steag - z. Dacă aveți un program de compresie bzip2 mai eficient instalat pe sistemul dvs., îl puteți utiliza modificând comanda după cum urmează:

Al treilea steag, f, spune că urmează numele fișierului arhivă, deci este întotdeauna ultimul din lista de steaguri. Rețineți că atunci când înlocuiți, numele variabilei este cuprins între acolade. Acest lucru se face pentru a evidenția în mod explicit variabila în linia ei înconjurătoare, eliminând astfel multe probleme potențiale. Extensiile la fișierul de arhivă nu sunt atribuite automat, tu însuți adaugi tot ce ai nevoie. Am enumerat proiecte și bin ca directoare de arhivă implicite, dar puteți nota aici numele celor mai valoroase directoare ale dvs.

Cuvântul cheie else deschide o ramură de execuție alternativă. Comenzile acestui bloc încep să funcționeze dacă verificarea condiției dă rezultatul „fals” (în exemplul nostru: „numărul parametrilor trecuți este diferit de zero”, adică utilizatorul a specificat numele directoarelor). În acest caz, comanda va arăta astfel:

Aici directoarele implicite sunt înlocuiteun șir de nume de directoare acceptate din exterior. Este posibil să acceptăm și să procesăm fiecare parametru extern separat, dar este mai convenabil pentru noi să trecem întregul șir.

La sfârșitul programului, se efectuează o altă verificare. În mediile Unix, toate comenzile returnează un cod de stare de ieșire pentru munca lor. Dacă comanda a fost finalizată cu succes, atunci returnează codul 0, altfel codul de ieșire va fi diferit de zero. Pentru a verifica succesul comenzii anterioare de arhivare, folosim o altă variabilă specială $?, care conține întotdeauna valoarea codului de ieșire al celei mai recente comenzi. Dacă în variabila $? conţine 0, adică fișierul de rezervă a fost creat cu succes, apoi îl mutăm în directorul de arhive:

și emite mesajul corespunzător:

Dacă verificarea a arătat că codul de ieșire al operațiunii de arhivare nu este egal cu zero, atunci este afișat un mesaj de eroare:

Acest lucru completează munca scriptului nostru de comandă.

Pentru a testa funcționarea programului nostru, trebuie să salvăm codul sursă descris mai sus într-un fișier, de exemplu, cu numele bckp, apoi, pentru comoditate, să îl facem executabil:

pentru a face copii de rezervă ale directoarelor implicite și

pentru a face copii de rezervă ale directoarelor listate (specificați numele directoarelor care există efectiv pe sistemul dvs., altfel veți primi un mesaj de eroare).

Puteți plasa fișierul bckp într-unul dintre directoarele specificate în variabila de sistem PATH. Cele mai preferate locații sunt /usr/local/bin sau $HOME/bin dacă aveți una. După aceea, puteți rula bckp ca o comandă de sistem.

Câteva cuvinte despre automatizarea backupului. În acest scop, servește programatorul cron al sistemului, care citește instrucțiunile de lucru de lafișier crontab special. Pentru a defini astfel de instrucțiuni, trebuie să creați și să editați fișierul crontab cu comanda:

Instrucțiunile sunt scrise într-un format strict definit (câmpurile sunt separate prin spații):

O opțiune pentru programarea operațiunilor de backup ar putea arăta astfel:

Aceasta înseamnă că scriptul de rezervă (trebuie să specificați calea completă către acest fișier) va fi executat la 23:30 în zilele de 10, 20 și 30 ale fiecărei luni, indiferent de ziua săptămânii. (Asteriscurile indică întregul interval de valori permise, în acest caz: în fiecare lună în al 4-lea câmp, orice zi a săptămânii în al 5-lea câmp)

Aici, backup-urile vor fi create la ora 5:00 miercuri și vineri din fiecare lună (asterisc în al 4-lea câmp), indiferent de număr (asterisc în al 3-lea câmp).

Puteți citi despre toate complexitățile programării în man 5 crontab.

Scriptul de backup discutat în acest articol are o funcționalitate modestă. Dar aceasta nu a fost sarcina lui principală, ci să-l facă pe cititor să înțeleagă ce se poate face pe linia de comandă și nu numai să copieze și să execute fișierul batch propus, ci să devină interesat de extinderea funcțiilor acestuia și să înceapă să exploreze vastele posibilități oferite de shell-uri de comandă. Și dacă cineva, după ce a citit acest articol, încearcă să îmbunătățească codul dat aici, sau își scrie propria versiune sau își implementează propria idee independentă, atunci voi considera că scopul principal a fost atins.

Alexey Snastin este un dezvoltator de software independent, consultant și traducător din engleză de literatură tehnică și educațională despre IT. Am participat la dezvoltarea aplicațiilor client/server de birou de rețea în limbaj C în mediul Linux.