Bash скриптове, част 2 цикли

Последния път говорихме за основите на програмирането за bash. Дори малкото, което вече е подредено, позволява на всеки да започне автоматизиране на работата в Linux. В този материал ще продължим историята за bash скриптовете, нека поговорим за контролните структури, които ви позволяват да извършвате повтарящи се действия. Говорим за цикли for и while, методи за работа с тях и практически примери за тяхното използване.

част

Предупреждение:Ползите са скрити в публикацията!

Bash shell поддържа for цикли, които ви позволяват да обикаляте поредици от стойности. Ето основната структура на такива цикли:

Във всяка итерация на цикъла следващата стойност от списъка ще бъде записана в променливата var. Следователно при първото преминаване на цикъла ще се използва първата стойност от списъка. Във втория - вторият и така нататък - докато цикълът стигне до последния елемент.

Итериране на прости стойности

Може би най-простият пример за for цикъл в bash скриптове е итерация върху списък от прости стойности:

Резултатът от този скрипт е показан по-долу. Ясно се вижда, че елементите от списъка последователно попадат в променливата $var. Това се случва, докато цикълът достигне последния от тях.

bash
Прост цикъл за

Моля, обърнете внимание, че променливата $var запазва стойността си при излизане от цикъла, нейното съдържание може да бъде променено, като цяло можете да работите с нея като с всяка друга променлива.

Итериране на комплексни стойности

Списъкът, използван за инициализиране на цикъла for, може да съдържа не само прости низове, състоящи се от една дума, но и цели фрази, които включват няколко думи и препинателни знаци. Например всичко може да изглежда така:

Ето какво се случва, след като този цикъл премине през списъка. Както можете да видите, резултатът е доста очакван.

Търсене на сложни стойностиTNW-CUS-FMP е промоционален код за 10% отстъпка от нашите услуги, наличен за активиране в рамките на 7 дни"

Инициализиране на цикъла със списък, получен от резултатите от командата

Друг начин за инициализиране на for цикъл е да му се предаде списък, който е резултат от някаква команда. Той използва заместване на команди, за да ги изпълни и да получи резултатите от тяхната работа.

Този пример използва командата cat за четене на съдържанието на файл. Полученият списък със стойности се предава на цикъла и се показва на екрана. Моля, обърнете внимание, че файлът, до който имаме достъп, съдържа списък с думи, разделени с нов ред, без интервали.

Цикъл, който итерира съдържанието на файл

Тук трябва да се отбележи, че такъв подход, ако се очаква обработка на данни ред по ред, няма да работи за файл с по-сложна структура, чиито редове могат да съдържат няколко думи, разделени с интервали. Цикълът ще обработва отделни думи, а не редове.

Ами ако изобщо не е това, което искате?

Разделители на полета

Причината за горната функция е специална променлива на средата, наречена IFS (Internal Field Separator), която ви позволява да зададете разделители на полета. По подразбиране bash shell третира следните знаци като разделители на полета:

  • пространство
  • Знак за раздел
  • Символ за подаване на ред

Ако bash срещне някой от тези знаци в данните, той приема, че е предшестван от следващата независима стойност в списъка.

За да разрешите проблема, можетевременно променете променливата на средата IFS. Ето как да го направите в bash скрипт, ако приемем, че имате нужда само от нов ред като разделител на полето:

След добавяне на тази команда към bash скрипт, тя ще работи както трябва, игнорирайки интервали и табулатори, считайки само нови редове за разделители на полета.

Ако този скрипт се изпълни, той ще изведе точно това, което се изисква от него, давайки при всяка итерация на цикъла достъп до следващия ред, записан във файла.

скриптове
Обхождане ред по ред на съдържанието на файл в forцикъл

Други знаци могат да бъдат разделители. Например, по-горе показахме съдържанието на файла /etc/passwd. Потребителските данни в редовете са разделени с двоеточие. Ако трябва да обработите такива редове в цикъл, IFS може да бъде конфигуриран така:

Обхождане на файлове, съдържащи се в директория

Една от най-честите употреби на for цикли в bash скриптове е да преминават през файлове в директория и да обработват тези файлове.

Например, ето как да изброявате файлове и папки:

Ако сте се занимавали с предишния материал в тази поредица от статии, трябва да разберете как работи конструкцията if-then, както и как да разграничите файл от папка. Ако ви е трудно да разберете горния код, прочетете отново този материал.

Това ще изведе скриптът.

част
Показване на съдържанието на папката

Когато проверяваме условието в оператор if, поставяме името на променливата в кавички. Това се прави, защото името на файла или папката може да съдържа интервали.

C-стил for loops

Ако сте запознати с езика за програмиране C, синтаксисът за описание на bash for циклите може да ви се стори странен, тъй като очевидно сте свикнали с подобно описание.цикли:

Bash скриптовете могат да използват for цикли, които изглеждат много подобни на цикли в стил C, но с няколко разлики. Диаграмата на цикъла с подобен подход изглежда така:

В bash това може да се напише така:

И ето един работещ пример:

Този код ще отпечата списък с числа от 1 до 10.

bash
Лупинг в стил C

докато цикъл

Конструкцията for не е единственият начин за организиране на цикли в bash скриптове. Тук можете също да използвате цикли while. В такъв цикъл можете да зададете команда за проверка на определено условие и да изпълните тялото на цикъла, докато провереното условие върне нула или сигнал за успешно завършване на някаква операция. Когато условието на цикъла върне ненулева стойност, което означава грешка, цикълът ще спре.

Ето схема за организиране на цикли, докато докато командата за проверка на условието до други команди готово

Нека да разгледаме примерен скрипт с цикъл като този:

На входа на цикъла променливата $var1 се проверява дали е по-голяма от нула. Ако е така, тялото на цикъла се изпълнява, като се изважда единица от стойността на променливата. Това се случва при всяка итерация, докато отпечатваме стойността на променливата в конзолата, преди да бъде променена. Веднага щом $var1 стане 0, цикълът спира.

част
Резултатът от цикъла while

Ако не модифицирате променливата $var1, това ще доведе до навлизане на скрипта в безкраен цикъл.

Вложени цикли

Можете да използвате всякакви команди в тялото на цикъла, включително стартиране на други цикли. Такива конструкции се наричат ​​вложени цикли:

По-долу е какво ще изведе този скрипт. Както можете да видите, първо се изпълнява първата итерация на външния цикъл, след това три итерации на вътрешния цикъл, след завършването му той започва отнововъншен контур, след това отново - вътрешен.

част
Вложени цикли

Обработка на файлово съдържание

Най-често вложените цикли се използват за обработка на файлове. И така, външният цикъл итерира през редовете на файла, а вътрешният цикъл вече работи с всеки ред. Например, ето как изглежда файлът /etc/passwd:

Този скрипт има два цикъла. Първият итерира през редовете, като използва знака за нов ред като разделител. Вътрешният е зает с анализиране на низове, чиито полета са разделени с двоеточие.

bash
Обработка на файлови данни

Този подход може да се използва, когато се обработват файлове във формат CSV или всякакви подобни файлове, записвайки, ако е необходимо, разделителен знак в променливата на средата IFS.

Управление на цикъла

Може би след влизане в цикъла ще е необходимо да го спрете, когато променливата на цикъла достигне определена стойност, която не съответства на първоначално зададеното условие за прекратяване на цикъла. Трябва ли да се изчака нормалното завършване на цикъла в такава ситуация? Разбира се, че не и в такива случаи следните две команди ще бъдат полезни:

прекъсване на командата

Тази команда ви позволява да прекъснете изпълнението на цикъла. Може да се използва както за цикли for, така и за цикли while:

Такъв цикъл при нормални условия ще премине през целия списък със стойности от списъка. В нашия случай обаче неговото изпълнение ще бъде прекъснато, когато променливата $var1 е равна на 5.

Ранно излизане от цикъла for

Ето същото нещо, но за цикъла while:

Командата break, изпълнена, когато стойността на $var1 стане 5, прекъсва цикъла. Същият изход като в предишния пример ще бъде изведен към конзолата.

продължи команда

Когато тази команда се срещне в тялото на цикъла, текущата итерация приключва преждевременно.и следващият започва, докато излизането от цикъла не се случва. Нека да разгледаме командата за продължаване в for цикъла:

Когато условието вътре в цикъла е вярно, т.е. когато $var1 е по-голямо от 5 и по-малко от 10, обвивката изпълнява командата за продължаване. Това води до пропускане на командите, останали в тялото на цикъла, и преминаване към следваща итерация.

скриптове
Командата за продължаване в цикъла for

Обработка на изход, работещ в цикъл

Изходните данни в цикъл могат да бъдат обработени или чрез пренасочване на изхода, или чрез предаването му на тръбопровода. Това се прави чрез добавяне на команди за обработка на изхода след израза done.

Например, вместо да показвате на екрана какво се извежда в цикъла, можете да запишете всичко във файл или да го прехвърлите някъде другаде:

Обвивката ще създаде файла myfile.txt и ще пренасочи изхода на конструкцията for към този файл. Нека отворим файла и се уверим, че съдържа точно това, което очакваме.

Пренасочване на изходния цикъл към файл

Пример: Намиране на изпълними файлове

Нека използваме това, което вече сме покрили, и да напишем нещо полезно. Например, ако трябва да разберете кои точно изпълними файлове са налични в системата, можете да сканирате всички папки, записани в променливата на средата PATH. Вече разполагаме с целия арсенал от инструменти, които са ни необходими за това, просто трябва да го съберем заедно:

Такъв скрипт, малък и неусложнен, направи възможно получаването на списък с изпълними файлове, съхранявани в папки от PATH.

bash
Търсене на изпълними файлове в папки от PATH

Днес говорихме за циклите for и while в bash скриптовете, как да ги изпълняваме, как да ги контролираме. Вече знаете как да обработвате низове с различни разделители в цикли, знаете как да пренасочвате данните, показани вцикли, към файлове, как да преглеждате и анализирате съдържанието на директории.

Ако приемем, че сте разработчик на bash скриптове, който знае за тях само това, което е посочено в първата част от тази поредица от статии, и в тази, втората, тогава вече можете да напишете нещо полезно. Предстои третата част, след като се справите с която, ще научите как да предавате параметри и превключватели на командния ред на bash скриптове и какво да правите с всичко това.