Bash сценарийлері: басы

Bash сценарийлері: басы
Bash сценарийлері 2-бөлім: циклдар
Bash сценарийлері, 3-бөлім: Пәрмен жолы параметрлері және қосқыштар
Bash сценарийлері 4-бөлім: енгізу және шығару
Bash сценарийлері, 5-бөлім: сигналдар, фондық тапсырмалар, сценарийді басқару
Bash сценарийлері, 6-бөлім: Функциялар және кітапхананы дамыту
Bash сценарийлері, 7-бөлім: sed және мәтінді өңдеу
Bash сценарийлері, 8-бөлім: awk деректерді өңдеу тілі
Bash сценарийлері 9-бөлім: Тұрақты өрнектер
Bash сценарийлері 10-бөлім: практикалық мысалдар
Bash сценарийлері, 11-бөлім: интерактивті утилиталарды күту және автоматтандыру

Бүгін біз bash сценарийлері туралы сөйлесетін боламыз. Бұл - пәрмен жолы сценарийлері, bash қабығы үшін жазылған. Zsh, tcsh, ksh сияқты басқа қабықтар бар, бірақ біз bash-ге назар аударамыз. Бұл материал барлығына арналған, жалғыз шарт - жұмыс істеу мүмкіндігі командалық жол Linux

Bash сценарийлері: басы

Пәрмен жолы сценарийлері - бұл пернетақтадан енгізілетін, файлдарға жиналатын және қандай да бір ортақ мақсатпен біріктірілетін бірдей пәрмендердің жинақтары. Бұл жағдайда топтардың жұмысының нәтижелері тәуелсіз мәнге ие болуы немесе басқа командалар үшін кіріс деректері ретінде қызмет етуі мүмкін. Сценарийлер жиі орындалатын әрекеттерді автоматтандырудың қуатты тәсілі болып табылады.

Bash сценарийлері: басы

Сонымен, егер пәрмен жолы туралы айтатын болсақ, ол нүктелі үтірмен бөлінген енгізу арқылы бірден бірнеше пәрменді орындауға мүмкіндік береді:

pwd ; whoami

Шындығында, егер сіз мұны терминалда қолдансаңыз, екі пәрменді қамтитын бірінші bash сценарийі әлдеқашан жазылған. Бұл осылай жұмыс істейді. Алдымен команда pwd ағымдағы жұмыс каталогы туралы ақпаратты, содан кейін пәрменді көрсетеді whoamiретінде кірген пайдаланушы туралы ақпаратты көрсетеді.

Бұл тәсілді қолдана отырып, бір жолда қалағаныңызша командаларды біріктіруге болады, жалғыз шектеу - бағдарламаға берілетін аргументтердің максималды саны. Бұл шектеуді келесі пәрмен арқылы анықтауға болады:

getconf ARG_MAX

Пәрмен жолы - тамаша құрал, бірақ қажет болған сайын оған пәрмендерді енгізу керек. Егер біз файлға командалар жинағын жазып, оларды орындау үшін сол файлды жай ғана шақырсақ ше? Шындығында, біз айтып отырған файл пәрмен жолы сценарийі деп аталады.

Bash сценарийлері қалай жұмыс істейді

Пәрменді пайдаланып бос файл жасаңыз touch. Оның бірінші жолы қандай қабықшаны қолданатынымызды көрсетуі керек. Бізді қызықтырады bash, сондықтан файлдың бірінші жолы болады:

#!/bin/bash

Бұл файлдағы басқа жолдар қабық өңдемейтін түсініктемелерді көрсету үшін хэш белгісін пайдаланады. Дегенмен, бірінші жол ерекше жағдай, хэштен кейін леп белгісі бар (бұл реттілік деп аталады) шебанг) және оған апаратын жол bash, жүйеге сценарийдің арнайы жасалғанын көрсетіңіз bash.

Қабық командалары жол арнасымен, түсініктемелер хэш белгісімен бөлінген. Мынадай көрінеді:

#!/bin/bash
# This is a comment
pwd
whoami

Мұнда, пәрмен жолындағы сияқты, командаларды нүктелі үтірмен бөлінген бір жолға жазуға болады. Дегенмен, пәрмендерді әртүрлі жолдарға жазсаңыз, файлды оқу оңайырақ болады. Кез келген жағдайда қабық оларды өңдейді.

Сценарий файлының рұқсаттарын орнату

Файлға ат беріп сақтаңыз myscript, ал bash сценарийін жасау жұмысы дерлік аяқталды. Енді бұл файлды орындалатын етіп жасау ғана қалады, әйтпесе оны іске қосып көрсеңіз, қате пайда болады. Permission denied.

Bash сценарийлері: басы
Қате конфигурацияланған рұқсаттары бар сценарий файлын іске қосу әрекеті

Файлды орындалатын етіп жасайық:

chmod +x ./myscript

Енді оны орындауға тырысайық:

./myscript

Рұқсаттарды орнатқаннан кейін бәрі қажетінше жұмыс істейді.

Bash сценарийлері: басы
bash сценарийі сәтті іске қосылды

Хабарды шығару

Linux консоліне мәтін шығару үшін пәрменді пайдаланыңыз echo. Келіңіздер, осы факт туралы білімімізді қолданып, сценарийді өңдеп, ондағы командалар арқылы шығарылатын деректерге түсініктемелер қосайық:

#!/bin/bash
# our comment is here
echo "The current directory is:"
pwd
echo "The user logged in is:"
whoami

Бұл жаңартылған сценарийді іске қосқаннан кейін орын алады.

Bash сценарийлері: басы
Сценарийден хабарламаларды шығару

Енді пәрмен арқылы түсіндірме жазбаларды көрсете аламыз echo. Егер сіз Linux құралдарын пайдаланып файлды өңдеуді білмесеңіз немесе пәрменді бұрын көрмеген болсаңыз echo, қараңыз бұл материал.

Айнымалыларды пайдалану

Айнымалылар басқа пәрмендермен пайдалану үшін пәрмендердің нәтижелері сияқты ақпаратты сценарий файлында сақтауға мүмкіндік береді.

Жеке пәрмендерді олардың нәтижелерін сақтамай орындауда ешқандай қате жоқ, бірақ бұл тәсіл өзінің мүмкіндіктерінде айтарлықтай шектеулі.

Bash сценарийлерінде қолдануға болатын айнымалылардың екі түрі бар:

  • Қоршаған ортаның айнымалылары
  • Пайдаланушы айнымалылары

Қоршаған ортаның айнымалылары

Кейде қабық командалары кейбір жүйелік деректермен жұмыс істеуі керек. Ағымдағы пайдаланушының үй каталогын көрсетудің мысалы:

#!/bin/bash
# display user home
echo "Home for the current user is: $HOME"

Жүйе айнымалысын пайдалана алатынымызды ескеріңіз $HOME қос тырнақшада бұл жүйенің оны тануына кедергі болмайды. Жоғарыдағы сценарийді орындасаңыз, бұл сіз аласыз.

Bash сценарийлері: басы
Сценарийде орта айнымалысын пайдалану

Экранда доллар белгісін көрсету қажет болса ше? Мынаны қолданып көрейік:

echo "I have $1 in my pocket"

Жүйе тырнақшаға алынған жолда доллар белгісін анықтайды және біз айнымалыға сілтеме жасадық деп есептейді. Сценарий анықталмаған айнымалының мәнін көрсетуге тырысады $1. Бұл бізге керегі емес. Не істеу?

Бұл жағдайда доллар белгісінің алдында қашу таңбасын, кері қиғаш сызықты пайдалану көмектеседі:

echo "I have $1 in my pocket"

Сценарий енді күтілетін нәрсені шығарады.

Bash сценарийлері: басы
Доллар белгісін басып шығару үшін қашу ретін пайдалану

Пайдаланушы айнымалылары

Ортаның айнымалы мәндеріне қоса, bash сценарийлері сценарийде өзіңіздің айнымалы мәндеріңізді анықтауға және пайдалануға мүмкіндік береді. Мұндай айнымалылар сценарий орындауды аяқтағанша мәнді сақтайды.

Жүйелік айнымалылар сияқты, пайдаланушы айнымалыларына доллар белгісі арқылы қол жеткізуге болады:
TNW-CUS-FMP - қызметтерімізге 10% жеңілдікке арналған промокод, оны 7 күн ішінде қосуға болады.

#!/bin/bash
# testing variables
grade=5
person="Adam"
echo "$person is a good boy, he is in grade $grade"

Мұндай сценарийді іске қосқаннан кейін осылай болады.

Bash сценарийлері: басы
Сценарийдегі теңшелетін айнымалылар

Пәрменді ауыстыру

Bash сценарийлерінің ең пайдалы мүмкіндіктерінің бірі - бұл ақпаратты сценарий файлының кез келген жерінде пайдалануға мүмкіндік беретін пәрмен шығысынан ақпаратты шығару және оны айнымалыларға тағайындау мүмкіндігі.

Мұны екі жолмен жасауға болады.

  • «`» кері белгісін пайдалану
  • Дизайн бойынша $()

Бірінші тәсілді пайдаланған кезде, кері белгінің орнына бір тырнақшаны қоспау үшін абай болыңыз. Пәрмен осындай екі белгішенің ішінде болуы керек:

mydir=`pwd`

Екінші тәсілде дәл осылай жазылған:

mydir=$(pwd)

Және сценарий келесідей болуы мүмкін:

#!/bin/bash
mydir=$(pwd)
echo $mydir

Оның жұмысы кезінде команданың шығысы pwdайнымалы мәнде сақталады mydir, оның мазмұны пәрменді пайдаланып echo, консольге өтеді.

Bash сценарийлері: басы
Пәрмен нәтижелерін айнымалы мәнде сақтайтын сценарий

Математикалық амалдар

Сценарий файлында математикалық операцияларды орындау үшін келесідей құрылымды пайдалануға болады $((a+b)):

#!/bin/bash
var1=$(( 5 + 5 ))
echo $var1
var2=$(( $var1 * 2 ))
echo $var2

Bash сценарийлері: басы
Сценарийдегі математикалық амалдар

егер-онда басқару құрылымы

Кейбір сценарийлерде пәрменді орындау ағынын басқару қажет. Мысалы, белгілі бір мән бестен үлкен болса, бір әрекетті орындау керек, әйтпесе басқа. Бұл көптеген жағдайларда қолданылады және мұнда басқару құрылымы бізге көмектеседі if-then. Ең қарапайым түрде ол келесідей көрінеді:

if команда
then
команды
fi

Міне жұмыс мысалы:

#!/bin/bash
if pwd
then
echo "It works"
fi

Бұл жағдайда, егер команда орындалса pwdсәтті аяқталады, консольде «бұл жұмыс істейді» мәтіні көрсетіледі.

Бар білімімізді пайдаланып, күрделі сценарий жазайық. Бізге белгілі бір пайдаланушыны табу керек делік /etc/passwd, және егер сіз оны таба алсаңыз, оның бар екенін хабарлаңыз.

#!/bin/bash
user=likegeeks
if grep $user /etc/passwd
then
echo "The user $user Exists"
fi

Бұл сценарийді іске қосқаннан кейін осылай болады.

Bash сценарийлері: басы
Пайдаланушы іздеу

Мұнда біз команданы қолдандық grepфайлдағы пайдаланушыны іздеу /etc/passwd. Егер команда grepсізге таныс емес, оның сипаттамасын табуға болады осында.

Бұл мысалда, егер пайдаланушы табылса, сценарий сәйкес хабарламаны көрсетеді. Пайдаланушы табылмаса ше? Бұл жағдайда сценарий бізге ештеңе айтпастан жай ғана орындалуды аяқтайды. Біз оның бізге де бұл туралы айтқанын қалаймыз, сондықтан кодты жақсартамыз.

if-then-else басқару құрылымы

Бағдарлама сәтті іздеудің және сәтсіздіктің нәтижелерін де хабарлауы үшін біз құрылысты қолданамыз if-then-else. Бұл қалай жұмыс істейді:

if команда
then
команды
else
команды
fi

Егер бірінші пәрмен нөлді қайтарса, бұл оның сәтті орындалғанын білдіреді, шарт ақиқат болады және орындау тармақ бойынша жүрмейді else. Әйтпесе, сәтсіздікті немесе жалған нәтижені көрсететін нөлден басқа нәрсе қайтарылса, келесі пәрмендер else.

Келесі сценарийді жазайық:

#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
else
echo "The user $user doesn’t exist"
fi

Оның өлім жазасына кесілгені суға кетті else.

Bash сценарийлері: басы
if-then-else конструкциясымен сценарийді іске қосу

Ал, әрі қарай жүріп, күрделірек жағдайлар туралы өзімізден сұрап көрейік. Бір емес, бірнеше шартты тексеру қажет болса ше? Мысалы, егер қажет пайдаланушы табылса, бір хабарлама көрсетілуі керек, егер басқа шарт орындалса, басқа хабарлама көрсетілуі керек және т.б. Мұндай жағдайда ұялы жағдайлар бізге көмектеседі. Бұл келесідей көрінеді:

if команда1
then
команды
elif команда2
then
команды
fi

Егер бірінші пәрмен нөлді қайтарса, бұл оның сәтті орындалуын көрсетеді, бірінші блоктағы командалар орындалады. then, әйтпесе, егер бірінші шарт жалған болса және екінші пәрмен нөлді қайтарса, кодтың екінші блогы орындалады.

#!/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

Мұндай сценарийде, мысалы, пәрменді пайдаланып жаңа пайдаланушы жасауға болады useradd, егер іздеу нәтиже бермесе немесе басқа пайдалы нәрсе жасаса.

Сандарды салыстыру

Сценарийлерде сандық мәндерді салыстыруға болады. Төменде сәйкес пәрмендердің тізімі берілген.

n1 -eq n2true мәнін қайтарады, егер n1 тең n2.
n1 -ge n2 true мәнін қайтарады, егер n1артық немесе тең n2.
n1 -gt n2true мәнін қайтарады, егер n1 артық n2.
n1 -le n2true мәнін қайтарады, егер n1аз немесе тең n2.
n1 -lt n2n1 мәнінен кіші болса, шын мәнін қайтарады n2.
n1 -ne n2true мәнін қайтарады, егер n1тең емес n2.

Мысал ретінде салыстыру операторларының бірін қолданып көрейік. Өрнектің шаршы жақшаға алынғанын ескеріңіз.

#!/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"
fi

Бұл пәрмен шығаратын нәрсе.

Bash сценарийлері: басы
Сценарийлердегі сандарды салыстыру

Айнымалы мән val15-тен жоғары болса, тармақ орындалады thenсалыстыру операторы және консольде сәйкес хабарлама көрсетіледі.

Жолды салыстыру

Сценарийлер жол мәндерін де салыстыра алады. Салыстыру операторлары өте қарапайым болып көрінеді, бірақ жолды салыстыру операцияларының белгілі бір мүмкіндіктері бар, біз оларды төменде қарастырамыз. Мұнда операторлар тізімі берілген.

str1 = str2 Жолдарды теңдікке тексереді, егер жолдар бірдей болса, ақиқат мәнін қайтарады.
str1 != str2Жолдар бірдей болмаса, true мәнін қайтарады.
str1 < str2true мәнін қайтарады, егер str1Азырақ str2.
str1 > str2 true мәнін қайтарады, егер str1гөрі көбірек str2.
-n str1 Ұзындығы болса, шын мәнін қайтарады str1Нөлден жоғары.
-z str1Ұзындығы болса, шын мәнін қайтарады str1нөлге тең.

Сценарийдегі жолдарды салыстырудың мысалы:

#!/bin/bash
user ="likegeeks"
if [$user = $USER]
then
echo "The user $user  is the current logged in user"
fi

Сценарийді орындау нәтижесінде келесіні аламыз.

Bash сценарийлері: басы
Сценарийлердегі жолдарды салыстыру

Міне, жолды салыстырудың бір ерекшелігін атап өткен жөн. Атап айтқанда, «>» және «<» операторлары кері қиғаш сызықпен қашу керек, әйтпесе қате туралы хабарлар пайда болмаса да, сценарий дұрыс жұмыс істемейді. Сценарий «>» белгісін шығыс қайта бағыттау пәрмені ретінде түсіндіреді.

Міне, осы операторлармен жұмыс кодта қалай көрінеді:

#!/bin/bash
val1=text
val2="another text"
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi

Міне, сценарийдің нәтижелері.

Bash сценарийлері: басы
Жолды салыстыру, ескерту берілді

Сценарий орындалғанымен, ескерту беретінін ескеріңіз:

./myscript: line 5: [: too many arguments

Бұл ескертуден құтылу үшін біз қорытынды жасаймыз $val2 қос тырнақшаға:

#!/bin/bash
val1=text
val2="another text"
if [ $val1 > "$val2" ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi

Қазір бәрі өз қалауымен жұмыс істейді.

Bash сценарийлері: басы
Жолды салыстыру

«>» және «<» операторларының тағы бір ерекшелігі – олардың бас және кіші әріптермен жұмыс істеу тәсілі. Бұл мүмкіндікті түсіну үшін келесі мазмұны бар мәтіндік файлды дайындаймыз:

Likegeeks
likegeeks

Оған ат қойып сақтап алайық myfile, содан кейін терминалда келесі пәрменді іске қосыңыз:

sort myfile

Ол файлдағы жолдарды келесідей сұрыптайды:

likegeeks
Likegeeks

команда sort, әдепкі бойынша жолдарды өсу ретімен сұрыптайды, яғни біздің мысалдағы кіші әріп бас әріптен кішірек. Енді сол жолдарды салыстыратын сценарий дайындаймыз:

#!/bin/bash
val1=Likegeeks
val2=likegeeks
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi

Егер сіз оны іске қоссаңыз, бәрі керісінше болып шығады - кіші әріп енді бас әріптен үлкенірек.

Bash сценарийлері: басы
Сценарий файлындағы сұрыптау пәрмені және жолдарды салыстыру

Салыстыру командаларында бас әріптер кіші әріптерден кішірек болады. Мұндағы жолды салыстыру таңбалардың ASCII кодтарын салыстыру арқылы орындалады, сұрыптау реті осылайша таңба кодтарына байланысты.

команда sort, өз кезегінде жүйе тілінің параметрлерінде көрсетілген сұрыптау ретін пайдаланады.

Файлды тексеру

Мүмкін, келесі пәрмендер bash сценарийлерінде жиі қолданылады. Олар файлдарға қатысты әртүрлі шарттарды тексеруге мүмкіндік береді. Міне, осы командалардың тізімі.

-d fileФайлдың бар-жоғын және каталог екенін тексереді.
-e fileФайлдың бар-жоғын тексереді.
-f file Файлдың бар-жоғын және файл екенін тексереді.
-r fileФайлдың бар-жоғын және оқуға болатынын тексереді.
-s file ПФайлдың бар-жоғын және бос еместігін тексереді.
-w fileФайлдың бар-жоғын және жазылу мүмкіндігін тексереді.
-x fileФайлдың бар-жоғын және орындалатынын тексереді.
file1 -nt file2 Оның жаңарақ екенін тексереді file1қарағанда file2.
file1 -ot file2Ескі екенін тексереді file1қарағанда file2.
-O file Файлдың бар-жоғын және ағымдағы пайдаланушыға тиесілі екенін тексереді.
-G fileФайлдың бар-жоғын және оның топ идентификаторы ағымдағы пайдаланушының топ идентификаторына сәйкес келетінін тексереді.

Бұл пәрмендерді, сондай-ақ бүгін талқыланған басқа да көптеген командаларды есте сақтау оңай. Олардың атаулары әртүрлі сөздердің аббревиатурасы бола отырып, олар жүргізетін тексерулерді тікелей көрсетеді.

Пәрмендердің бірін тәжірибеде қолданып көрейік:

#!/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"
fi

Бұл сценарий бұрыннан бар каталог үшін оның мазмұнын көрсетеді.

Bash сценарийлері: басы
Каталогтың мазмұнын тізімдеу

Қалған командалармен тәжірибе жасай аласыз деп ойлаймыз, олардың барлығы бірдей принцип бойынша қолданылады.

Нәтижелері

Бүгін біз bash сценарийлерін жазуды қалай бастау керектігі туралы сөйлестік және кейбір негізгі нәрселерді қарастырдық. Шын мәнінде, bash бағдарламалау тақырыбы өте үлкен. Бұл мақала 11 материалдан тұратын үлкен серияның бірінші бөлімінің аудармасы. Дәл қазір жалғастырғыңыз келсе, мұнда осы материалдардың түпнұсқаларының тізімі берілген. Ыңғайлы болу үшін сіз жаңа ғана оқыған аудармасы осында берілген.

  1. Bash сценарийі қадам бойынша — мұнда біз bash сценарийлерін құруды қалай бастау керектігі туралы айтып отырмыз, айнымалыларды пайдалану қарастырылады, шартты құрылымдар, есептеулер, сандарды, жолдарды салыстыру және файлдар туралы ақпаратты табу сипатталады.
  2. Bash Scripting 2-бөлім, Bash the awesome — мұнда for және while циклдерімен жұмыс істеу ерекшеліктері ашылады.
  3. Bash сценарийі 3-бөлім, Параметрлер және опциялар — бұл материал пайдаланушы енгізетін және файлдардан оқуға болатын деректермен жұмыс істейтін сценарийлерге берілуі мүмкін командалық жолдың параметрлері мен кілттеріне арналған.
  4. Bash сценарийінің 4-бөлімі, енгізу және шығару - бұл жерде біз файл дескрипторлары және олармен жұмыс істеу, енгізу, шығару, қате ағындары және шығысты қайта бағыттау туралы айтып отырмыз.
  5. Bash сценарийі 5-бөлім, Сигалдар және жұмыс — бұл материал Linux сигналдарына, оларды сценарийлерде өңдеуге және кесте бойынша сценарийлерді іске қосуға арналған.
  6. Bash сценарийі 6-бөлім, Функциялар — мұнда сіз сценарийлердегі функцияларды құру және пайдалану және кітапханаларды әзірлеу туралы біле аласыз.
  7. Bash сценарийі 7-бөлім, sed пайдалану — бұл мақала sed ағынды мәтіндік редактормен жұмыс істеуге арналған.
  8. Bash сценарийі 8-бөлім, awk пайдалану — бұл материал awk мәліметтерді өңдеу тілінде бағдарламалауға арналған.
  9. Bash сценарийі 9-бөлім, тұрақты өрнектер — мұнда сіз bash сценарийлерінде тұрақты өрнектерді пайдалану туралы оқи аласыз.
  10. Bash сценарийі 10-бөлім, практикалық мысалдар — мұнда пайдаланушыларға жіберуге болатын хабарламалармен жұмыс істеу әдістері, сондай-ақ дискіні бақылау әдісі.
  11. Bash сценарийі 11-бөлім, күту пәрмені — бұл материал Expect құралына арналған, оның көмегімен интерактивті утилиталармен өзара әрекеттесуді автоматтандыруға болады. Атап айтқанда, біз күтілетін сценарийлер және олардың bash сценарийлерімен және басқа бағдарламалармен әрекеттесуі туралы айтып отырмыз.

Бұл мақалалар топтамасының құнды ерекшеліктерінің бірі қарапайымнан бастап, кез келген деңгейдегі пайдаланушылар үшін қолайлы, ол бірте-бірте өте маңызды тақырыптарға алып келеді, бұл барлығына Linux пәрмен жолы сценарийлерін жасауда ілгерілеуге мүмкіндік береді. .

Құрметті оқырмандар! Біз bash бағдарламалау гуруларынан өздерінің шеберлік шыңына қалай жеткені туралы әңгімелесуін, құпияларымен бөлісуін сұраймыз және біз алғашқы сценарийін жазғандардан әсер күтеміз.

Bash сценарийлері: басы

Сауалнамаға тек тіркелген пайдаланушылар қатыса алады. Кіру, өтінемін.

Қалған мақалалар топтамасын аударуым керек пе?

  • Ия!

  • Жоқ керек емес

1030 пайдаланушы дауыс берді. 106 пайдаланушы қалыс қалды.

Ақпарат көзі: www.habr.com

пікір қалдыру