Блог ИТ склеротика. Основы Bash: циклы

Страницы

Расширенный поиск в статьях блога

13 марта 2012 г.

Основы Bash: циклы

Одно из основных правил системного администрирования можно выразить так: если вам нужно часто делать одно и то же, напишите сценарий, и пусть он делает эту работу за вас. Если вам необходимо выполнять какое-то действие внутри сценария несколько раз, то вам стоит воспользоваться циклами. В GNU Bash вы можете создавать циклы при помощи конструкций for, while и until.
Если вы когда-нибудь интересовались программированием,то, скорее всего, вы уже знакомы с этими конструкциями. Если же вы, подобно мне, изучаете Bash, не имея за плечами опыта программирования, использование циклов может оказаться не достаточно очевидным для понимания. Начнём с определения различий между различными типами циклов, а затем перейдём к примерам.
Цикл for предназначен для повторения действий до тех пор, пока они все не будут выполнены. Представьте, например, что у вас есть каталог с изображениями, и вам необходимо преобразовать их из одного формата в другой. Вы можете использовать цикл forсовместно с программой convert из пакета ImageMagick (или какой-либо другой программой), например, для того, чтобы преобразовать изображения из формата JPEG в формат PNG. Или, например, вам может понадобиться преобразовать множество звуковых файлов из MP3 в OGG Vorbis.
Цикл while используется для повторения действий пока выполняется (является истинным) какое-то условие. Цикл until работает несколько по другому: он выполняет действие до тех пор, пока не выполнится условие. Так, например, вы можете счётчик и выполнять действиедо тех пор, пока его значение не достигнет 10. Рассмотрим это более подробно на примерах.

Циклы for

Начнём с цикла for. Его формат таков:
for i in $( command ); do command $i; done

Если вы используете цикл for в скрипте, лучше отформатировать его так:


#!/bin/bash
for i in $( command ); do
command $i
done

Так, например, если вам нужно сделать резервные копии всех HTML-файлов, находящихся в каталоге, вы можете использовать следующую команду:


for i in $( ls *html ); do cp $i $i.bak; done

Здесь создаётся локальная переменная $i, выполняется команда ls *html, результаты выполнения которой и будут являться данными, инициализирующими значение переменной$i при каждой итерации цикла (в нашем примере это будет список файлов, возвращаемый командой ls, по одному за каждую итерацию). Далее, выполняется команда cp, которой среди параметров передаётся переменная $i.

Кто-то может спросить, обязательно ли использовать букву «i» в качестве имени переменной? Нет. Вы можете использовать любое корректное  для Bash имя переменной. Конечно же, в сценариях лучше использовать более осмысленные имена переменных, вроде$input или $html.

Я привёл очень краткий и простой пример использования цикла for. Вместо команды, выполняющейся в блоке do, используйте echo для того, чтобы увидеть параметры, передаваемые ей. Это очень полезная практика на стадии тестирования скриптов, а также хороший способ помочь вам более подробно разобраться с работой for.

while и until


Рассмотрим теперь конструкции while и until. Также, мы немного воспользуемсяусловными выражениями bash. В нашем примере мы будем использовать их для того, чтобы определять, например, является ли значение переменной большим или меньшим, чем число X; существует ли файл и является ли он каталогом. Вы также можете использовать условные выражения для определения, например, доступности файла для чтения или присутствия в его правах доступа GID-бита.

Давайте попробуем сделать что-нибудь простое, например, создадим несколько пустых файлов. В жизни это вряд ли вам пригодится, но в качестве примера — самое оно.


#!/bin/bash
i=0
while [ $i -lt 22 ]
do
  touch $i
  i=$[$i+1]
done

Этот скрипт создаст 22 файла с именами от 0 до 21. Цикл будет работать до тех пор, показначение переменной $i меньше (-lt) 22.

Теперь давайте избавимся от созданных файлов при помощи цикла until:


#!/bin/bash
i=0
until [ $i -eq 22 ]
do
  rm $i
  i=$[$i+1]
done

Здесь мы заменили while на until, а в условном выражении заменили «меньше» (-lt) на«равно» (-eq). Таким образом, наш скрипт будет работать до тех пор, пока значение $i не достигнет 22. И вместо touch мы использовали rm, чтобы удалять файлы, а не создавать их. Просто, не так ли?

По мотивам Linux.Com

.

Счетчик тИЦ и PR Яндекс.Метрика Msn bot last visit powered by MyPagerank.NetYahoo bot last visit powered by MyPagerank.Net ping fast  my blog, website, or RSS feed for Free