Циклы в bash
for
С-like конструкция for
Конструкция, объединяющая код инициализации, условие завершения и код, выполняемый в начале каждой итерации:
Явные значения
Передать в for можно явный список значений из чисел:
из строк:
из переменных:
из результата выполнения команд - отдельных или их конвейеров:
из результата команды seq:
Но вместо такой конструкции лучше использовать более эффективный и понятный способ - С-like конструкцию:
seq вообще удобно использовать для последовательности float чисел, указав начальное значение, приращение на каждом шаге и конечное значение:
Существует вариант с фигурными скобками, но с проблемами совместимости с разными версиями bash, потому что поддержка фигурных скобок появилась в bash 3.0, а дополнение нулями числовых значений (в начале) в bash 4.0:
Нули в начале числа
В bash 4.0 и выше, если любой из первых двух членов в выражении вида
{начало..конец..шаг}
начинается с нуля, то переменная цикла будет значением одинаковой длины и дополняться нулями слева.
Примеры:
{098..100}
→098,099,100
{98..0100}
→0098,0099,0100
Можно и передать несколько подстановок и вообще итераторов:
Бесконечные цикл for
Перечисление значений в списке
Это, кстати, python-like конструкция:
"${person_list[@]}"
- конструкция перечисления всех значений в списке. Подстановка производится при подготовке команды к выполнению. Содержимое массива извлекается до передачи управления оператору for, то есть, цикл получается значения, как если бы они были введены явно:
Тоже самое можно делать с ассоциативными массивами/хешами (аналогия - словари в python):
Еще пример:
Кавычки
Значения в массивах могут иметь пробелы, поэтому использование кавычек в случае с "${person_list[@]}"
позволит избежать неожиданных результатов:
А кавычки помогут избежать этого:
Еще один момент: к синтаксисе списка можно использовать знаки @ и * для перечисления всех его элементов. Конструкция ${someList[*]}
дает тот же результат за исключением случая, когда она заключена в кавычки: "${someList[*]}"
вернет все значения внутри одной строки:
Перебор аргументов сценария
Для перебора всех аргументов сценария можно использовать специальные переменные командной оболочки $@ и $* , которые вызывают список всех аргументов сценария, но при заключении в кавычки дают разный результат: несколько строк и в одну строку.
Есть два хороших варианта перебора циклом for всех аргументов сценария:
В любом случае, комментарии лишними не будут (для тех, кто не шарит за bash).
while и until
C while всё просто:
until это ! while. Выполняет тело цикла, пока код условия выхода ненулевой.
Удобно в случае ожидания какого-то события, например, перезагрузки узла:
Соусы:
Книга “Идиомы Bash” → Глава 2. Язык циклов
Книга “Bash и кибербезопасность” → Глава 2. “Основы работы с bash”