Оболонка bash дозволяє використовувати цикли. Ці структури дозволяють виконувати блок команд кілька разів (від 0 до нескінченності) відповідно до статично визначеного значення, динамічно або за умови:
while
until
for
select
Незалежно від того, який цикл використовувався, команди, які потрібно повторити, розміщуються між словамиdo та done.
Структура while / do / done обчислює команду, розміщену після while.
Якщо ця команда вірна ($? = 0), виконуються команди, розміщені між do та done. Потім сценарій повертається до початку, щоб знову оцінити команду.
Коли оцінювана команда є помилковою ($? != 0), оболонка відновить виконання сценарію за першою командою після завершення.
Синтаксис структури умовного циклу while:
while command
do
command if $? = 0
done
Приклад використання умовної структури while:
while [[ -e /etc/passwd ]]
do
echo "The file exists"
done
Якщо оцінювана команда не змінюється, цикл буде нескінченним і оболонка ніколи не виконає команди, розміщені після сценарію. Це може бути навмисно, але це також може бути помилка. Тож вам слід бути дуже обережними з командами, які керують циклом, і знайти спосіб вийти з нього.
Щоб вийти з циклу while, ви повинні переконатися, що команда, яка оцінюється, більше не є істинною, що не завжди можливо.
Існують команди, які дозволяють змінювати поведінку циклу:
bash # to avoid being disconnected after the "exit 1
exit 1
echo $?
1
Команда exit негайно завершує сценарій. Можна вказати код повернення сценарію, надавши його як аргумент (від 0 до 255). Якщо аргумент не вказано, код повернення останньої команди сценарію буде передано до змінної $?.
Структура select / do / done дозволяє відобразити меню з кількома варіантами вибору та запитом на введення.
Кожен елемент у списку має пронумерований вибір. Коли ви вводите вибір, вибране значення призначається змінній після select (створеної для цієї мети).
Потім він виконує команди, розміщені між do та done із цим значенням.
Змінна PS3 містить запрошення ввести вибір;
Змінна REPLY поверне номер вибору.
Для виходу з циклу потрібна команда break.
Примітка
Структура select дуже корисна для невеликих і простих меню. Щоб налаштувати більш повне відображення, потрібно використовувати команди echo і read у циклі while.
Синтаксис структури умовного циклу select:
PS3="Your choice:"
select variable in var1 var2 var3
do
commands
done
Приклад використання умовної структури select:
PS3="Your choice: "
select choice in coffee tea chocolate
do
echo "You have chosen the $REPLY: $choice"
done
Якщо запустити цей сценарій, він покаже щось на зразок цього:
1) Coffee
2) Tea
3) Chocolate
Your choice : 2
You have chosen choice 2: Tea
Your choice:
Структура for / do / done призначає перший елемент списку змінній після for (створеної з цієї нагоди). Потім він виконує команди, розміщені між do та done із цим значенням. Потім сценарій повертається на початок, щоб призначити робочій змінній наступний елемент списку. Після використання останнього елемента оболонка відновлює виконання першої команди після done.
Синтаксис структури циклу в списку значень for:
for variable in list
do
commands
done
Приклад використання умовної структури for:
for file in /home /etc/passwd /root/fic.txt
do
file $file
done
Будь-яку команду, яка створює список значень, можна розмістити після in за допомогою підвиконання.
Якщо змінна IFS містить $' \t\n', цикл for займатиме кожен словорезультату цієї команди як список елементів для циклу.
Якщо змінна IFS містить $'\t\n' (тобто без пробілів), цикл for братиме кожен рядок результату ця команда.
Це можуть бути файли в каталозі. У цьому випадку змінна прийматиме як значення кожне зі слів наявних імен файлів:
for file in $(ls -d /tmp/*)
do
echo $file
done
Це може бути файл. У цьому випадку змінна прийматиме як значення кожне слово, що міститься у файлі, який переглядається, від початку до кінця:
cat my_file.txt
first line
second line
third line
for LINE in $(cat my_file.txt); do echo $LINE; done
first
line
second
line
third line
line
Щоб прочитати файл рядок за рядком, потрібно змінити значення змінної середовища IFS.
IFS=$'\t\n'
for LINE in $(cat my_file.txt); do echo $LINE; done
first line
second line
third line