Остерегайтесь бесконечных циклов!
Возможность зацикливания – очень мощная функция сценариев bash. Циклы имеют множество вариантов использования.
В этой статье вы изучите три разные структуры цикла bash. Вы также узнаете, как использовать циклы для обхода элементов массива.
Кроме того, вы узнаете, как использовать операторы break и continue для управления циклами, и, наконец, вы узнаете, как создавать бесконечные циклы.
Циклы For – это один из трех различных типов структур цикла, которые вы можете использовать в bash. Есть два разных стиля написания цикла for.
Если вы знакомы с языком программирования C или C ++, то вы узнаете следующий синтаксис цикла for:
for ((initialize ; condition ; increment)); do [COMMANDS] done
Используя вышеупомянутый синтаксис в стиле C, следующий цикл for распечатает «Привет друг» десять раз:
for ((i = 0 ; i < 10 ; i++)); do echo "Привет друг" done
Цикл for сначала инициализирует целочисленную переменную i нулевым значением, затем проверяет условие (i <10) ; если true, то цикл выполняет строковое эхо «Привет друг» и увеличивает переменную i на 1 , а затем цикл запускается снова и снова, пока i не станет больше 10 .
destroyer@andreyex:~$ bash hello.sh Привет друг Привет друг Привет друг Привет друг Привет друг Привет друг Привет друг Привет друг Привет друг Привет друг
Также существует другой вариант синтаксиса цикла for, который особенно полезен, если вы работаете со списком файлов (или строк), диапазоном чисел, массивами, выводом команды и т. д. Синтаксис списка/диапазона для цикла имеет следующую форму :
for item in [LIST]; do [COMMANDS] done
Например, следующий цикл for делает то же самое, что и цикл for в стиле C, который вы создали в предыдущем разделе:
for i in {1..10}; do echo "Привет друг" done
Приведенный ниже сценарий var.sh выведет все файлы и каталоги, существующие в каталоге/var :
#!/bin/bash for i in /var/*; do echo $i done
Ниже приведен пример вывода при запуске сценария var.sh:
destroyer@andreyex:~$ ./var.sh /var/backups /var/cache /var/crash /var/lib /var/local /var/lock /var/log /var/mail /var/metrics /var/opt /var/run /var/snap /var/spool /var/tmp
Цикл while – еще один популярный и интуитивно понятный цикл, который можно использовать в сценариях bash. Общий синтаксис цикла while следующий:
while [ condition ]; do [COMMANDS] done
Например, в следующем сценарии 3×10.sh используется цикл while, который выводит первые десять чисел, кратных числу три:
#!/bin/bash num=1 while [ $num -le 10 ]; do echo $(($num * 3)) num=$(($num+1)) done
Вот результат выполнения вышеуказанного скрипта:
destroyer@andreyex:~$ ./3x10.sh 3 6 9 12 15 18 21 24 27 30
Сначала он инициализировал переменную num равной 1; тогда цикл while будет выполняться до тех пор, пока num меньше или равно 10. Внутри корпуса в то время цикла, эхо – команда печатает на NUM умножается на три , а затем он увеличивает Num от 1.
Если вы работаете с C/C ++, возможно, вы ищете цикл do-while, но его нет в bash.
В bash существует еще один вид цикла. Синтаксис цикла while совпадает с синтаксисом цикла while:
until [ condition ]; do [COMMANDS] Done
Ключевое различие между циклом until и циклом while заключается в условии проверки. Цикл while будет выполняться до тех пор, пока выполняется условие проверки; с другой стороны, цикл до тех пор, пока условие проверки не будет ложным!
Например, вы можете легко создать сценарий 3×10.sh с циклом «пока» вместо цикла «until»; уловка здесь в том, чтобы отрицать условие теста:
#!/bin/bash num=1 until [ $num -gt 10 ]; do echo $(($num * 3)) num=$(($num+1)) done
Обратите внимание, что отрицание условия проверки [$ num -le 10]; равно [$ num -gt 10];
Теперь, когда вы знакомы с циклами в сценариях bash
Если вы с самого начала следите за этой серией статей, вы должны быть знакомы с массивами в bash.
Циклы For часто являются наиболее популярным выбором, когда дело доходит до перебора элементов массива.
Например, следующий сценарий prime.sh выполняет итерацию и распечатывает каждый элемент в массиве простых чисел:
#!/bin/bash prime=(2 3 5 7 11 13 17 19 23 29) for i in "${prime[@]}"; do echo $i done
Это результат работы скрипта prime.sh:
destroyer@andreyex:~$ ./prime.sh 2 3 5 7 11 13 17 19 23 29
Иногда вы можете захотеть преждевременно выйти из цикла или пропустить итерацию цикла. Для этого вы можете использовать операторы break и continue.
Оператор break завершает выполнение цикла и переключает управление программой на следующую команду или инструкцию, следующую за циклом.
Например, следующий цикл будет печатать только числа от одного до трех:
for ((i=1;i<=10;i++)); do echo $i if [ $i -eq 3 ]; then break fi done
Вы также можете использовать оператор continue, чтобы пропустить итерацию цикла. Цикл продолжается и переходит к следующей итерации, но команды после операторов continue пропускаются в этой частичной итерации.
Например, следующий скрипт odd.sh будет печатать только нечетные числа от одного до десяти, поскольку он пропускает все четные числа:
#!/bin/bash for ((i=0;i<=10;i++)); do if [ $(($i % 2)) -ne 1 ]; then continue fi echo $i done
Вот результат, который печатает нечетные числа:
destroyer@andreyex:~$ ./odd.sh 1 3 5 7 9
Бесконечный цикл – это цикл, который продолжается вечно; это происходит, когда условие проверки цикла всегда истинно.
В большинстве случаев бесконечные циклы являются результатом человеческой логической ошибки.
Например, тот, кто может захотеть создать цикл, который печатает числа от 1 до 10 в порядке убывания, может по ошибке создать следующий бесконечный цикл:
for ((i=10;i>0;i++)); do echo $i done
Проблема в том, что цикл продолжает увеличивать переменную i на 1 . Чтобы исправить это, вам нужно заменить i ++ на i– следующим образом:
for ((i=10;i>0;i--)); do echo $i done
В некоторых случаях вы можете намеренно создать бесконечные циклы, чтобы дождаться выполнения внешнего условия в системе. Вы можете легко создать бесконечный цикл for следующим образом:
for ((;;)); do [COMMANDS] done
Если вместо этого вы хотите создать бесконечный цикл while, вы можете создать его следующим образом:
while [ true ]; do [COMMANDS] done
На этом мы подошли к концу нашей статьи из серии Bash для начинающих. Надеюсь, вам понравилось делать цикл в bash!
Следите за новостями на следующей неделе, так как вы узнаете, как повторно использовать код в сценариях bash, создавая функции.