Sot do të flasim për bash-skripte. Këto janë , të shkruara për shell-in bash. Ekzistojnë edhe shell-e të tjera, si zsh, tcsh, ksh, por ne do të përqendrohemi te bash. Ky material është i destinuar për çdo person të interesuar, kushdo që di të punojë në Linux.
Skenarët e linjës së komandës janë grupe të të njëjtave komanda, të cilat mund të jepen nga tastiera, të mbledhura në skedarë dhe të lidhura me ndonjë qëllim të përbashkët. Në këtë mënyrë, rezultatet e punës së komandave mund të kenë vlerë të vetme ose të shërbejnë si input për komandat e tjera. Skenarët janë një mënyrë e fuqishme për të automatizuar veprime të përsëritura shpesh.
Pra, nëse flasim për linjën e komandës, ajo lejon ekzekutimin e disa komandave në të njëjtën kohë, duke i dhënë ato përmes pikës së gjashtë:
pwd ; whoami Në të vërtetë, nëse e keni provuar këtë në terminalin tuaj, skenari juaj i parë bash, në të cilin përfshihen dy komanda, tashmë është shkruar. Ai punon kështu. Së pari, komanda pwd jep në ekran informacionin rreth drejtorisë aktuale të punës, pastaj komanda whoamitregon të dhënat për përdoruesin nën të cilin jeni regjistruar.
Duke pĂ«rdorur njĂ« qasje tĂ« tillĂ«, mund tĂ« kombinoni sa mĂ« shumĂ« komanda nĂ« njĂ« linjĂ«, kufizimi Ă«shtĂ« vetĂ«m numri maksimal i argumenteve qĂ« mund tâi kaloni programit. PĂ«rcaktoni kĂ«tĂ« kufizim me njĂ« komandĂ« tĂ« tillĂ«:
getconf ARG_MAXLinja e komandĂ«s Ă«shtĂ« njĂ« mjet i shkĂ«lqyer, por ju duhen tĂ« jepni komandat çdo herĂ« qĂ« keni nevojĂ« pĂ«r to. ĂfarĂ« nĂ«se e regjistroni njĂ« grup komandash nĂ« njĂ« skedar dhe thjesht thirrni kĂ«tĂ« skedar pĂ«r tâi ekzekutuar ato? NĂ« fakt, ai skedar pĂ«r tĂ« cilin po flasim quhet skenar i linjĂ«s sĂ« komandĂ«s.
Si janë të organizuara bash-skenarët
Krijoni një skedar të zbrazët duke përdorur komandën touch. Në rreshtin e tij të parë duhet të tregojmë se cila shell do të përdorim. Na intereson bash, prandaj rreshti i parë i skedarit do të jetë kështu:
#!/bin/bash Në rreshtat e tjerë të këtij skedari, simboli # përdoret për të shënuar komente që shell-i nuk i proceson. Megjithatë, rreshti i parë është një rast i veçantë, këtu # që ndiqet nga një shkronjë e madhe (!), quhet ) dhe rruga për bash, i tregon sistemit se skripti është krijuar pikërisht për bash.
Komandat e shell-it ndahen me shenjën e kalimit në rresht, komentet shenohen me simbolin #. Ja si duket:
#!/bin/bash
# This is a comment
pwd
whoamiKëtu, si në komandën e linjës, mund të shkruani komandat në një rresht, duke i ndarë me pikëpresje. Megjithatë, nëse shkruani komanda në rreshta të ndryshëm, skedari lexohet më lehtë. Në çdo rast, shell-i do t'i përpunojë ato.
Caktimi i lejeve për skedarin e skriptit
Ruani skedarin, duke i dhënë atij emrin myscript, dhe puna për krijimin e skriptit bash është pothuajse përfunduar. Tani mbetet vetëm ta bëni këtë skedar ekzekutues, ndryshe, përpiqeni ta filloni, do të hasni në gabimin Permission denied.

Përpjekja për të ekzekutuar skedarin me leje të gabuara të vendosura
Të bëjmë skedarin ekzekutues:
chmod +x ./myscriptTani le t'i japim një përpjekje për ta ekzekutuar:
./myscriptPas caktimit të lejeve, gjithçka funksionon siç duhet.

Ekzekutimi i suksesshëm i skriptit bash
Shfaqja e mesazheve
Për të shfaqur tekst në terminalin Linux përdoret komanda echo. Le të shfrytëzojmë njohuritë tona në këtë fakt dhe të redaktojmë skriptin tonë, duke shtuar shpjegime për të dhënat që japin komandat që tashmë janë në të:
#!/bin/bash
# our comment is here
echo "The current directory is:"
pwd
echo "The user logged in is:"
whoamiJa çfarë do të marrë pas ekzekutimit të skriptit të përditësuar.

Shfaqja e mesazheve nga skripti
Tani mund të shfaqim tekste shpjeguese, duke përdorur komandën echo. Nëse nuk e dini se si ta redaktoni skedarin duke përdorur mjetet e Linux-it, ose nuk keni hasur më parë me komandën echo, shikoni material.
Përdorimi i variablave
Variablat lejojnë që të ruhet informacione në skedarin e skriptit, për shembull - rezultatet e ekzekutimit të komandave për t'u përdorur nga komandat e tjera.
Nuk ka asgjë të keqe në ekzekutimin e komandave të veçanta pa ruajtur rezultatet e tyre, por mundësitë e këtij qasjes janë shumë të kufizuara.
Ekzistojnë dy lloje variablash që mund të përdoren në skriptat bash:
- Variablat mjedisorë
- Variablat e përdoruesit
Variablat mjedisorë
Ndonjëherë në komandat e shell-it duhet të punoni me disa të dhëna sistemore. Ja si mund të shfaqni direktorinë e shtëpisë së përdoruesit aktual:
#!/bin/bash
# display user home
echo "Home for the current user is: $HOME" Vini re se mund të përdorim variablin sistemor $HOME në dyfisha, kjo nuk do ta pengojë sistemin ta identifikojë. Ja çfarë do të ndodhë nëse ekzekutojmë skenarin e mësipërm.

Përdorimi i variablave të ambientit në skenar
Po nëse duam të shfaqim simbolin e dollarit? Le ta provojmë kështu:
echo "I have $1 in my pocket" Sistemi do ta zbulojĂ« shenjĂ«n e dollarit nĂ« vargun e mbyllur me dysh tĂ« hapura dhe do tĂ« vendosĂ« se po i referohemi njĂ« variabli. Skripti do tĂ« pĂ«rpiqet tĂ« shfaqĂ« vlerĂ«n e njĂ« variabli tĂ« paqartĂ« $1. Kjo nuk Ă«shtĂ« ajo qĂ« na nevojitet. ĂfarĂ« tĂ« bĂ«jmĂ«?
Në një situatë të tillë do të ndihmojë përdorimi i simbolit kontrollues, një kthesë të prapme, përpara shenjës së dollarit:
echo "I have $1 in my pocket"Tani skenari do të japë pikërisht atë që pritet.

Përdorimi i sekuencës kontrolluese për të shfaqur simbolin e dollarit
Variablat e përdoruesit
Përveç variablave të ambientit, bash-skriptet lejojnë që të përcaktoni dhe përdorni variabla të tuaj në skenar. Variabla të tilla ruhen deri sa të përfundojë ekzekutimi i skenarit.
Ashtu si në rastin e variablave sistemorë, mund të referoheni te variablat e përdoruesit duke përdorur shenjën e dollarit:
TNW-CUS-FMP â njĂ« kod promocional pĂ«r 10% zbritje nĂ« shĂ«rbimet tona, i disponueshĂ«m pĂ«r aktivizim pĂ«r 7 ditĂ«
#!/bin/bash
# testing variables
grade=5
person="Adam"
echo "$person is a good boy, he is in grade $grade"Ja çfarë do të ndodhë pas ekzekutimit të këtij skenari.

Variablat e përdoruesit në skenar
Zëvendësimi i komandave
Një nga mundësitë më të dobishme të bash-skripteve është mundësia për të nxjerrë informacion nga dalja e komandave dhe ta caktoni atij variablave, duke mundësuar përdorimin e këtij informacioni kudo në skenar.
Kjo mund të bëhet në dy mënyra.
- Me ndihmën e simbolit të prapme "`"
- Me ndihmën e konstrukcionit
$()
Duke përdorur qasjen e parë, sigurohuni që të mos ngatërroni simbolin e prapme me thonjëzat e vetme. Komanda duhet të mbyllet me dy nga këto simbole:
mydir=`pwd`Me qasjen e dytë, e njëjta shënohet kështu:
mydir=$(pwd)Dhe skripti, rezultatisht, mund të duket kështu:
#!/bin/bash
mydir=$(pwd)
echo $mydir Gjatë ekzekutimit të tij, dalja e komandës pwddo të ruhet në variablën mydir, përmbajtja e së cilës, me ndihmën e komandës echo, do të kalojë në konsolë.

Një skript që ruan rezultatet e punës së komandës në një variabël
Operacione Matematike
Për të kryer operacione matematikore në skedarin e skriptit, mund të përdorni konstruksionin e tipit $((a+b)):
#!/bin/bash
var1=$(( 5 + 5 ))
echo $var1
var2=$(( $var1 * 2 ))
echo $var2 
Operacione Matematike në skenar
Konstruksioni udhëheqës if-then
NĂ« disa skenare Ă«shtĂ« e nevojshme tĂ« menaxhohet rrjedha e ekzekutimit tĂ« komandave. PĂ«r shembull, nĂ«se njĂ« vlerĂ« Ă«shtĂ« mĂ« e madhe se pesĂ«, duhet tĂ« kryhet njĂ« veprim, pĂ«rndryshe â njĂ« tjetĂ«r. NjĂ« gjĂ« e tillĂ« Ă«shtĂ« e aplikueshme nĂ« shumĂ« situata, dhe kĂ«tu do tĂ« na ndihmojĂ« konstruksioni udhĂ«heqĂ«s if-then. NĂ« formĂ«n e saj mĂ« tĂ« thjeshtĂ« ajo duket kĂ«shtu:
if komanda
then
komanda
fiJa një shembull funksional:
#!/bin/bash
if pwd
then
echo "It works"
fi Në këtë rast, nëse ekzekutimi i komandës pwdtë mbaron me sukses, në konsolë do të shfaqet teksti «it works».
Le të përdorim njohuritë që kemi dhe të shqyrtojmë një skenar më të komplikuar. Le të themi se duhet të gjejmë një përdorues në /etc/passwd, dhe nëse e kemi gjetur, të njoftojmë që ai ekziston.
#!/bin/bash
user=likegeeks
if grep $user /etc/passwd
then
echo "The user $user Exists"
fiJa çfarë rezultati kemi pas ekzekutimit të këtij skripti.

Kërkimi i përdoruesit
Këtu e kemi përdorur komandën greppër të kërkuar përdoruesin në skedarin /etc/passwd. Nëse komanda grepnuk ju është e njohur, përshkrimi i saj mund të gjendet .
Në këtë shembull, nëse përdoruesi gjendet, skripti do të shfaqë mesazhin përkatës. Dhe nëse nuk arrijmë ta gjejmë përdoruesin? Në këtë rast, skripti do të përfundojë ekzekutimin pa na njoftuar. Do të dëshironim që ai të na thoshte edhe për këtë, prandaj do ta përmirësojmë kodin.
Konstruksioni udhëheqës if-then-else
Për të mundësuar që programi të njoftojë si për rezultatet e kërkimit me sukses, ashtu edhe për dështim, do të përdorim konstrukcionin if-then-else. Ja si është ndërtuar:
if komanda
then
komanda
else
komanda
fi Nëse komanda e parë kthen zero, që do të thotë se është ekzekutuar me sukses, kushti do të del të jetë i vërtetë dhe ekzekutimi nuk do të shkojë në degën e else. Ndryshe, nëse kthehet ndonjë gjë që ndryshon nga zero, e cila do të tregonte një dështim, ose një rezultat të rremë, do të ekzekutohen komandat që ndodhen pas else.
Le të shkruajmë një skript të tillë:
#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
else
echo "The user $user doesnât exist"
fi Ekzekutimi i tij shkoi në degën else.

Ekzekutimi i skriptit me konstruksionin if-then-else
BashkojmĂ« mĂ« tej dhe tĂ« reflektojmĂ« mbi njĂ« çështje mĂ« komplekse. ĂfarĂ« ndodh nĂ«se ndihmojmĂ« qĂ« tĂ« verifikojmĂ« disa kushte? PĂ«r shembull, nĂ«se pĂ«rdoruesi i dĂ«shiruar Ă«shtĂ« gjetur, duhet tĂ« shfaqim njĂ« mesazh, nĂ«se pĂ«rmbushet njĂ« kusht tjetĂ«r â duhet tĂ« shfaqim njĂ« mesazh tjetĂ«r dhe kĂ«shtu me radhĂ«. NĂ« njĂ« situatĂ« tĂ« tillĂ«, kushtet e ngulitura do ta ndihmojnĂ« kĂ«tĂ« proces. Kjo duket nĂ« kĂ«tĂ« mĂ«nyrĂ«:
if komandë1
then
komandat
elif komandë2
then
komandat
fi Nëse komandë e parë kthen zero, që tregon se është realizuar me sukses, do të ekzekutohen komandat në bllokun e parë. then, ndryshe, nëse kushti i parë është i rremë dhe nëse komandë e dytë kthen zero, do të ekzekutohet blloku i dytë të kodit.
#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
elif ls /home
then
echo "The user doesnât exist but anyway there is a directory under /home"
fi Në një skenar të tillë mund, për shembull, të krijoni një përdorues të ri duke përdorur komandën useradd, nëse kërkimi nuk ka dhënë rezultate, ose të bëni diçka tjetër të dobishme.
Krahasimi i numrave
Në skenarët e mund të krahasohen vlerat numerike. Më poshtë është lista e komandave përkatëse.
n1 -eq n2Kthehet një vlerë e vërtetë nësen1është e barabartë men2.
n1 -ge n2Kthehet një vlerë e vërtetë nësen1më shumë ose e barabartë men2.
n1 -gt n2Kthehet një vlerë e vërtetë nësen1më shumën2.
n1 -le n2Kthehet një vlerë e vërtetë nësen1më pak ose e barabartë men2.
n1 -lt n2Kthehet një vlerë e vërtetë nëse n1 është më pakn2.
n1 -ne n2Kthehet një vlerë e vërtetë nësen1nuk është e barabartë men2.
Si shembull, të provojmë një nga operatorët e krahasimit. Vini re se shprehja është e mbyllur në kllapa.
#!/bin/bash
val1=6
if [ $val1 -gt 5 ]
then
echo "The test value $val1 is greater than 5"
else
echo "The test value $val1 is not greater than 5"
fiJa se çfarë do të shfaqë kjo komandë.

Krahasimi i numrave në skenarë
Vlera e variablit val1më shumë se 5, kështu që ekzekutohet dega thene operatorit të krahasimit dhe në konsolë shfaqet mesazhi përkatës.
Krahasimi i fjalive
Në skenarët mund të krahasohen edhe vlerat e fjalive. Operatorët e krahasimit duken mjaft të thjeshtë, megjithatë operacionet e krahasimit me fjalë kanë disa karakteristika të veçanta që do të trajtojmë më poshtë. Ja lista e operatorëve.
str1 = str2Kontrollon fjalitë për barazi, kthen vërtetësinë nëse fjalitë janë identike.
str1 != str2Kthehet e vërtetë nëse fjalitë nuk janë identike.
str1 < str2Kthehet e vërtetë nësestr1është më pak sestr2.
str1 > str2Kthehet e vërtetë nësestr1më shumë sestr2.
-n str1Kthehet e vërtetë nëse gjatësiastr1është më shumë se zero.
-z str1Kthehet e vërtetë nëse gjatësiastr1është e barabartë me zero.
Ja një shembull i krahasimit të fjalive në skenar:
#!/bin/bash
user ="likegeeks"
if [$user = $USER]
then
echo "The user $user  is the current logged in user"
fiSi rezultat i ekzekutimit të skenarit do të kemi këtë.

Krahasimi i fjalive në skenarë
Ja një veçori e krahasimit të vargjeve, për të cilën duhet të përmendet. Konkretisht, operatorët ">" dhe "" si një komandë për të redirektuar daljen.
Ja si duket puna me këta operatorë në kod:
#!/bin/bash
val1=text
val2="another text"
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fiJa rezultatet e punës së skriptit.

Krahasimi i vargjeve, duke gjeneruar një paralajmërim
Kujdesi me faktin se skripti, megjithëse ekzekutohet, jep një paralajmërim:
./myscript: linja 5: [: shumë argumente Për të eliminuar këtë paralajmërim, do të mbyllim $val2 në dyfisha:
#!/bin/bash
val1=text
val2="another text"
if [ $val1 > "$val2" ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fiTani gjithçka funksionon si duhen.

Krahasimi i fjalive
Një tjetër veçori e operatorëve ">" dhe "<" është mënyra se si ata punojnë me simbolet në rastet e sipërme dhe të poshtme. Për të kuptuar këtë veçori, do të përgatitim një skedar teksti me këtë përmbajtje:
Likegeeks
likegeeks Do ta ruajmë atë, duke i dhënë emrin myfile, pastaj do të ekzekutojmë një komandë të tillë në terminal:
sort myfileAjo do të rendisë vargjet nga skedari kështu:
likegeeks
Likegeeks Ekipa sort, në mënyrë të paracaktuar, rendit vargjet në rritje, domethënë letra të vogla në shembullin tonë janë më të vogla se ato të mëdha. Tani do të përgatitim një skript që do të krahasojë të njëjtat vargje:
#!/bin/bash
val1=Likegeeks
val2=likegeeks
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fiNĂ«se e nisim atĂ«, do tĂ« rezultojĂ« se Ă«shtĂ« e kundĂ«rta â letra e vogĂ«l tani Ă«shtĂ« mĂ« e madhe se ajo e madhe.

Komanda sort dhe krahasimi i vargjeve në skenarin e skenarit
Në komandat e krahasimit, shkronjat e mëdha janë më të vogla se ato të vogla. Krahasimi i vargjeve këtu bëhet duke krahasuar kodet ASCII të simboleve, rendi i renditjes, kështu, varet nga kodet e simboleve.
Ekipa sort, nga ana tjetër, përdor rendin e renditjes të caktuar në konfigurimet e gjuhës së sistemit.
Kontrolli i skedarëve
Mund të them se komandat e mëposhtme përdoren më shpesh në skriptet bash. Ato lejojnë kontrollimin e kushteve të ndryshme që lidhen me skedarët. Ja lista e këtyre komandave.
-d fileKontrollon nëse skedari ekziston dhe nëse është një direktor.
-e fileKontrollon nëse skedari ekziston.
-f fileKontrollon nëse skedari ekziston dhe është një skedar.
-r fileKontrollon nëse skedari ekziston dhe është i aksesueshëm për lexim.
-s file Pkontrollon nëse skedari ekziston dhe nuk është i zbrazët.
-w fileKontrollon nëse skedari ekziston dhe është i aksesueshëm për shkrim.
-x fileKontrollon nëse skedari ekziston dhe është ekzekutues.
file1 -nt file2Kontrollon nëse është më e re sefile1, sefile2.
file1 -ot file2Kontrollon nëse është më e vjetër sefile1, sefile2.
-O fileKontrollon nëse skedari ekziston dhe nëse pronari i tij është përdoruesi aktual.
-G fileKontrollon nëse skedari ekziston dhe nëse identifikuesi i tij i grupit përputhet me identifikuesin e grupit të përdoruesit aktual.
Këto komanda, si dhe shumë të tjera të shqyrtuara sot, janë të lehta për t'u mbajtur mend. Emrat e tyre, duke qenë akronime të fjalëve të ndryshme, tregojnë drejtpërdrejt kontrollimet që ata kryejnë.
Le të provojmë një nga komandat në praktikë:
#!/bin/bash
mydir=/home/likegeeks
if [ -d $mydir ]
then
echo "The $mydir directory exists"
cd $ mydir
ls
else
echo "The $mydir directory does not exist"
fiKy skript, për një direktor të ekzistueshëm, do të shfaqë përmbajtjen e tij.

Shfaqja e përmbajtjes së direktorëve
Besojmë se me komandat e tjera do të jeni në gjendje të eksperimentoni vetë, të gjitha ato aplikohen sipas të njëjtit parim.
Përfundime
Sot folĂ«m pĂ«r si tĂ« fillojmĂ« shkrimin e skripteve bash dhe shqyrtuam disa gjĂ«ra themelore. NĂ« tĂ« vĂ«rtetĂ«, tema e programimit nĂ« bash Ă«shtĂ« e madhe. Ky artikull Ă«shtĂ« njĂ« pĂ«rkthim i pjesĂ«s sĂ« parĂ« tĂ« njĂ« serie tĂ« madhe prej 11 materialesh. NĂ«se dĂ«shironi vazhdim menjĂ«herĂ« â ja lista e origjinaleve tĂ« kĂ«tyre materialeve. PĂ«r lehtĂ«si, kĂ«tu Ă«shtĂ« pĂ«rfshirĂ« edhe ai, pĂ«rkthimi i tĂ« cilit sapo lexuat.
- â kjo ka tĂ« bĂ«jĂ« me si tĂ« filloni krijimin e skripteve bash, shqyrtohet pĂ«rdorimi i variablave, pĂ«rshkruhen strukturat kushtore, llogaritjet, krahasimi i numrave, fjalĂ«ve, dhe identifikimi i informacionit mbi skedarĂ«t.
- â kĂ«tu shpalosen veçoritĂ« e punĂ«s me ciklet for dhe while.
- â ky material i dedikohet parametrave tĂ« vijĂ«s sĂ« komandĂ«s dhe çelĂ«save qĂ« mund t'i kaloni skripteve, punĂ«s me tĂ« dhĂ«na qĂ« fut pĂ«rdoruesi dhe qĂ« mund tĂ« lexoni nga skedarĂ«t.
- â kĂ«tu flitet pĂ«r deshkriptorĂ«t e skedarĂ«ve dhe punĂ«n me ta, pĂ«r rrjedhat e hyrjes, nxjerrjes, gabimeve, pĂ«r orientimin e nxjerrjes.
- â ky material i dedikohet sinjaleve tĂ« Linux, pĂ«rpunimit tĂ« tyre nĂ« skripte, ekzekutimit tĂ« skenarĂ«ve sipas njĂ« programi.
- â kĂ«tu mund tĂ« mĂ«soni pĂ«r krijimin dhe pĂ«rdorimin e funksioneve nĂ« skripte, pĂ«r zhvillimin e bibliotekave.
- â ky artikull Ă«shtĂ« i dedikuar punĂ«s me redaktorin e tekstit nĂ« rrjedhĂ« sed.
- â ky material i dedikohet programimit nĂ« gjuhĂ«n e pĂ«rpunimit tĂ« tĂ« dhĂ«nave awk.
- â kĂ«tu mund tĂ« lexoni rreth pĂ«rdorimit tĂ« shprehjeve tĂ« rregullta nĂ« skriptet bash.
- â kĂ«tu jepen teknikat e punĂ«s me mesazhet qĂ« mund t'u dĂ«rgohen pĂ«rdoruesve, si dhe metodologjia pĂ«r monitorimin e diskut.
- â ky material i dedikohet mjetit Expect, me ndihmĂ«n e tĂ« cilit mund tĂ« automatizoni ndĂ«rveprimin me utilitat interaktive. NĂ« veçanti, ky tekst flet pĂ«r skriptet expect dhe ndĂ«rveprimin e tyre me skriptet bash dhe programe tĂ« tjera.
Ne besojmë se një nga vlerat e çmuara të kësaj serie artikujsh është se ajo, duke filluar nga më e thjeshta, e përshtatshme për përdorues të çdo niveli, gradualisht kalon në tema mjaft serioze, duke iu dhënë mundësi të gjithë atyre që duan të përparojnë në krijimin e skripteve të linjës komandës Linux.
Të dashur lexues! Ju lutemi, guru të programimit në bash, ndani me ne se si arritët në majat e mjeshtërisë, ndihmoni me sekrete, dhe për ata që sapo kanë shkruar skriptin e tyre të parë, presim përvojat.
Vetëm përdoruesit e regjistruar mund të marrin pjesë në anketë. , ju lutem.
Të përkthehen pjesët e tjera të ciklit të artikujve?
Po!
Jo, nuk është e nevojshme
1030 përdorues kanë votuar. 106 përdorues janë ndalur.
Burimi: habr.com
