Сёння пагаворым аб bash-скрыптах. Гэта - сцэнары каманднага радка, напісаныя для абалонкі bash. Існуюць і іншыя абалонкі, напрыклад - zsh, tcsh, ksh, але мы засяродзімся на bash. Гэты матэрыял прызначаны для ўсіх жадаючых, адзіная ўмова - уменне працаваць у камандным радку Linux.
Сцэнары каманднага радка - гэта наборы тых жа самых каманд, якія можна ўводзіць з клавіятуры, сабраныя ў файлы і аб'яднаныя нейкай агульнай мэтай. Пры гэтым вынікі працы каманд могуць уяўляць або самастойную каштоўнасць, або служыць уваходнымі дадзенымі для іншых каманд. Сцэнары - гэта магутны спосаб аўтаматызацыі часта выкананых дзеянняў.
Такім чынам, калі казаць аб камандным радку, яна дазваляе выканаць некалькі каманд за адзін раз, увёўшы іх праз кропку з коскі:
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.
Спроба запуску файла сцэнара з няправільна наладжанымі дазволамі
Зробім файл выкананым:
chmod +x ./myscript
Цяпер паспрабуем яго выканаць:
./myscript
Пасля наладкі дазволаў усё працуе як трэба.
Паспяховы запуск bash-скрыпту
Вывад паведамленняў
Для вываду тэксту ў кансоль Linux прымяняецца каманда echo. Скарыстаемся веданнем гэтага факта і адрэдагуем наш скрыпт, дадаўшы тлумачэнні да дадзеных, якія выводзяць ужо наяўныя ў ім каманды:
#!/bin/bash
# our comment is here
echo "The current directory is:"
pwd
echo "The user logged in is:"
whoami
Вось што атрымаецца пасля запуску абноўленага скрыпту.
Вывад паведамленняў са скрыпту
Цяпер мы можам выводзіць тлумачальныя надпісы, выкарыстоўваючы каманду echo. Калі вы не ведаеце, як адрэдагаваць файл, карыстаючыся сродкамі Linux, ці раней не сустракаліся з камандай echo, зірніце на гэты матэрыял.
Выкарыстанне зменных
Зменныя дазваляюць захоўваць у файле сцэнара інфармацыю, напрыклад - вынікі працы каманд для выкарыстання іх іншымі камандамі.
Няма нічога дрэннага ў выкананні асобных каманд без захоўвання вынікаў іх працы, але магчымасці такога падыходу вельмі абмежаваны.
Існуюць два тыпу зменных, якія можна выкарыстоўваць у bash-скрыптах:
Пераменныя асяроддзі
Карыстальніцкія зменныя
Пераменныя асяроддзі
Часам у камандах абалонкі трэба працаваць з нейкімі сістэмнымі дадзенымі. Вось, напрыклад, як вывесці хатнюю дырэкторыю бягучага карыстальніка:
#!/bin/bash
# display user home
echo "Home for the current user is: $HOME"
Звярніце ўвагу на тое, што мы можам выкарыстоўваць сістэмную зменную $HOME у падвойных двукоссях, гэта не перашкодзіць сістэме яе распазнаць. Вось што атрымаецца, калі выканаць вышэйзгаданы сцэнар.
Выкарыстанне пераменнага асяроддзя ў сцэнары
А што, калі трэба вывесці на экран значок даляра? Паспрабуем так:
echo "I have $1 in my pocket"
Сістэма выявіць знак даляра ў радку, абмежаваным двукоссям, і вырашыць, што мы спаслаліся на зменную. Скрыпт паспрабуе вывесці на экран значэнне нявызначанай зменнай $1. Гэта не тое, што нам патрэбна. Што рабіць?
У падобнай сітуацыі дапаможа выкарыстанне кіраўніка знака, зваротнай касой рысы, перад знакам даляра:
echo "I have $1 in my pocket"
Цяпер сцэнарый выведзе менавіта тое, што чакаецца.
Выкарыстанне кіравальнай паслядоўнасці для вываду знака даляра
Карыстальніцкія зменныя
У дадатак да зменных асяроддзя, 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-скрыптоў - гэта магчымасць здабываць інфармацыю з высновы каманд і прызначаць яе зменным, што дазваляе выкарыстоўваць гэтую інфармацыю дзе заўгодна ў файле сцэнара.
Зрабіць гэта можна двума спосабамі.
З дапамогай значка зваротнага апострафа «`»
З дапамогай канструкцыі $()
Выкарыстоўваючы першы падыход, прасочыце за тым, каб замест зваротнага апострафа не ўвесці адзіночную двукоссе. Каманду трэба заключыць у два такія значкі:
mydir=`pwd`
Пры другім падыходзе тое ж самае запісваюць так:
mydir=$(pwd)
А скрыпт, у выніку, можа выглядаць так:
#!/bin/bash
mydir=$(pwd)
echo $mydir
У ходзе яго працы вывад каманды pwdбудзе захаваны ў зменнай mydir, змесціва якой, з дапамогай каманды echo, трапіць у кансоль.
Скрыпт, які захоўвае вынікі працы каманды ў зменнай
Матэматычныя аперацыі
Для выканання матэматычных аперацый у файле скрыпту можна выкарыстоўваць канструкцыю выгляду $((a+b)):
У некаторых сцэнарах трэба кіраваць патокам выканання каманд. Напрыклад, калі нейкае значэнне больш за пяць, трэба выканаць адно дзеянне, у адваротным выпадку - іншае. Падобнае дастасоўна ў вельмі шматлікіх сітуацыях, і тут нам дапаможа кіравальная канструкцыя if-then. У найболей простым выглядзе яна выглядае так:
if команда
then
команды
fi
А вось працоўны прыклад:
#!/bin/bash
if pwd
then
echo "It works"
fi
У дадзеным выпадку, калі выкананне каманды pwdзавершыцца паспяхова, у кансоль будзе выведзены тэкст "it works".
Скарыстаемся наяўнымі ў нас ведамі і напішам больш складаны сцэнар. Скажам, трэба знайсці нейкага карыстача ў /etc/passwd, і калі знайсці яго ўдалося, паведаміць аб тым, што ён існуе.
#!/bin/bash
user=likegeeks
if grep $user /etc/passwd
then
echo "The user $user Exists"
fi
Вось што атрымоўваецца пасля запуску гэтага скрыпту.
Пошук карыстальніка
Тут мы скарысталіся камандай 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.
Запуск скрыпту з канструкцыяй 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 n2Вяртае сапраўднае значэнне, калі n1 роўна n2. n1 -ge n2 Вяртае сапраўднае значэнне, калі n1больш або роўна n2. n1 -gt n2Вяртае сапраўднае значэнне, калі n1 больш n2. n1 -le n2Вяртае сапраўднае значэнне, калі n1менш ці роўна n2. n1 -lt n2Вяртае сапраўднае значэнне, калі n1 менш n2. n1 -ne n2Вяртае сапраўднае значэнне, калі 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
Вось што выведзе гэтая каманда.
Параўнанне лікаў у скрыптах
Значэнне зменнай val1больш за 5, у выніку выконваецца галіна thenаператара параўнання і ў кансоль выводзіцца адпаведнае паведамленне.
Параўнанне радкоў
У сцэнарах можна параўноўваць і радковыя значэнні. Аператары параўнання выглядаюць даволі проста, аднак у аперацый параўнання радкоў ёсць пэўныя асаблівасці, якіх мы закранем ніжэй. Вось спіс аператараў.
str1 = str2 Правярае радкі на роўнасць, вяртае ісціну, калі радкі ідэнтычныя.
str1 != str2Вяртае ісціну, калі радкі не ідэнтычныя. str1 < str2Вяртае ісціну, калі str1менш, чым str2. str1 > str2 Вяртае ісціну, калі 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
У выніку выкананні скрыпту атрымаем наступнае.
Параўнанне радкоў у скрыптах
Вось адна асаблівасць параўнання радкоў, аб якой варта згадаць. А менавіта, аператары ">" і "<" неабходна экранаваць з дапамогай зваротнай касой рысы, інакш скрыпт будзе працаваць няправільна, хоць паведамленняў аб памылках і не з'явіцца. Скрыпт інтэрпрэтуе знак ">" як каманду перанакіравання высновы.
Вось як праца з гэтымі аператарамі выглядае ў кодзе:
#!/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
Вось вынікі працы скрыпту.
Параўнанне радкоў, выведзенае папярэджанне
Звярніце ўвагу на тое, што скрыпт, хоць і выконваецца, выдае папярэджанне:
./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
Цяпер усё працуе як трэба.
Параўнанне радкоў
Яшчэ адна асаблівасць аператараў ">" і "<" заключаецца ў тым, як яны працуюць з сімваламі ў верхнім і ніжнім рэгістрах. Для таго, каб зразумець гэтую асаблівасць, падрыхтуем тэкставы файл з такім зместам:
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
Калі яго запусціць, апынецца, што ўсё наадварот - маленькая літара зараз больш вялікай.
Каманда sort і параўнанне радкоў у файле сцэнара
У камандах параўнання вялікія літары меншыя за малыя. Параўнанне радкоў тут выконваецца шляхам параўнання 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-праграмавання велізарная. Гэты артыкул з'яўляецца перакладам першай часткі вялікай серыі з 11 матэрыялаў. Калі вы хочаце працягу прама зараз - вось спіс арыгіналаў гэтых матэрыялаў. Для зручнасці сюды ўключаны і той, пераклад якога вы толькі што прачыталі.
Bash Script Step By Step - тут гаворка ідзе аб тым, як пачаць стварэнне bash-скрыптоў, разгледжана выкарыстанне зменных, апісаны ўмоўныя канструкцыі, вылічэнні, параўнанні лікаў, радкоў, высвятленне звестак аб файлах.
Bash Scripting Part 3, Parameters & options - гэты матэрыял прысвечаны параметрам каманднага радка і ключам, якія можна перадаваць скрыптам, працы з дадзенымі, якія ўводзіць карыстач, і якія можна чытаць з файлаў.
Bash Scripting Part 4, Input & Output — тут гаворка ідзе пра дэскрыптары файлаў і пра працу з імі, пра струмені ўводу, высновы, памылак, пра перанакіраванне высновы.
Bash Scripting Part 11, Expect Command - гэты матэрыял прысвечаны сродку Expect, з дапамогай якога можна аўтаматызаваць узаемадзеянне з інтэрактыўнымі ўтылітамі. У прыватнасці, тут ідзе гаворка пра expect-скрыпты і пра іх узаемадзеянне з bash-скрыптамі і іншымі праграмамі.
Мяркуем, адна з каштоўных уласцівасцяў гэтай серыі артыкулаў складаецца ў тым, што яна, пачынаючыся з самага простага, прыдатнага для карыстачоў любога ўзроўня, паступова вядзе да даволі сур'ёзных тэмаў, даючы шанец усім жадаючым рушыць наперад у справе стварэння сцэнараў каманднага радка Linux.
Паважаныя чытачы! Просім гуру bash-праграмавання расказаць пра тое, як яны дабраліся да вяршыняў майстэрства, падзяліцца сакрэтамі, а ад тых, хто толькі што напісаў свой першы скрыпт, чакаем уражанняў.
Толькі зарэгістраваныя карыстачы могуць удзельнічаць у апытанні. Увайдзіце, Калі ласка.