BashЯзык командного интерпретатора bash. Part 5. «Операторы цикла»

И вот настал черёд пятого топика цикла. В нём я продолжу рассматривать управляющие структуры командного интерпретатора bash. В предыдущем посте были разобраны условные операторы. Теперь настал черёд таких неотъемлемых языковых структур, как операторы цикла. Циклы, как и условия, являются теми инструментальными средствами, которые обеспечивают управление порядком исполнения команд.
Bash поддерживает циклы типа for, while, until и select. Теперь перейдём к подробному рассмотрению каждого из них.

Оператор цикла for

Общий синтаксис оператора for:
for переменная [in шаблон]
do
список команд
done

Цикл for в bash значительно отличается от цикла for в таких языках программирования, как C или PHP. Поэтому если вы программируете на C, вам нужно будет привыкнуть к этим отличиям, чтобы не путаться.
В результате подстановки шаблона получается список слов. При каждой итерации переменная принимает каждое последующее значение этого списка, и выполняются команды, стоящие между do и done. Итерации прекращаются по исчерпании слов в списке.
$ for day in Mon Tue Wed Thu Fri
do
echo “Сегодня $day”
done

Зарезервированные слова оператора for также можно писать в одну строчку, как это было в предыдущем посте для оператора if. Для этого нужно ставить ";". Перепишем предыдущий пример с учётом данной возможности:
$ for day in Mon Tue Wed Thu Fri; do echo “Сегодня $day”; done

Отсутствие конструкции [in шаблон] эквивалентно записи in $@. О параметре $@ говорилось в моей первой статье.

Оператор цикла while

Общий синтаксис оператора while:
while список1
do
список2
done

Сперва выполняется список1. Если он завершается успешно, т. е. возвращает нулевой код, управление переходит списку2. Итерации продолжаются до тех пор, пока результат выполнения списка1 не станет ненулевым. Например:
i=10
while [ $i –gt 0 ]; do
echo $i
i=$(($i-1))
done; echo 'end'


Оператор цикла until

Общий синтаксис оператора until:
until список1
do
список2
done

Сперва выполняется список1. Если он завершается неуспешно, то есть с ненулевым кодом возврата, управление переходит списку2. Итерации продолжаются до тех пор, пока результат выполнения списка1 не станет нулевым. Например:
i=10
until [ $i –lt 0 ]; do
echo $i
i=$(($i-1))
done; echo 'end'


Оператор цикла select

Общий синтаксис оператора select:
select переменная [in шаблон]
do
список
done

В результате подстановки шаблона получается список слов. К этим словам оператор добавляет порядковые номера и выводит весь набор в стандартный поток ошибок. Отсутствие конструкции [in шаблон] эквивалентно записи in $@. После этого выводится приглашение и считывается строка из стандартного потока ввода. Если строка содержит номер, соответствующий какому-либо слову из списка, то переменная получает его в качестве значения. Если подходящего слова не было найдено, то значением переменной становится пустая строка. После этого выполняется список команд, и итерации продолжаются до тех пор, пока в строке ввода не попадётся символ конца файла или пока в списке команд не встретится break или return.
Команды break и return служат для управления ходом выполнения цикла. Команда break прерывает исполнение цикла, в то время как return возвращает код результата (нулевой или ненулевой).
Оператор select полезен для создания нумерованных меню. Например, в каталоге ~/temp находится 3 файла: proto.txt, file.txt и readme. Пример фрагмента скрипта, позволяющего быстро просмотреть любой из них.
echo "Выберите файл для просмотра:"
select file in ~/temp/* Quit;
do
if [ -f $file ]; then cat $file;
else break;
fi
done

Запустив данный скрипт, мы увидим на экране:
Выберите файл для просмотра:
1) /home/istergul/temp/file.txt
2) /home/istergul/temp/proto.txt
3) /home/istergul/temp/readme
4) Quit


В следующем топике будут рассмотрены условные подстановки параметров. Жду ваших комментариев.

Комментарии (9)

Немного моего соуса в блюдо Istergul'а:
Пример for — 1ый(простой):
#Создает html-галерейку из jpg-картинок в текущей папке
for i in *.jpg; do
        echo "<IMG src=$i><HR>"
done > gallery.html


Пример for — 2ой(тоже простой, но из моего bash_history):
#Выкачевает рейтинг на сегодня с одного сайта
for i in {1..22};do  
        wget -nv https://open-life.org/people/good/page$i -O -|zcat
done > reiting_$(date +%y%m%d).html


Пример while — 1ый(бесконечный цикл):
#Сидюк-хронометр
while : ; do 
        eject; sleep 2; eject -2
done 


Пример while — 2ой(использование в построчной обработке файла)
#Подсчитать сумарный размер jpg-файлов в текущей папке
ls -l *.jpg| (  
        while read Perm nL Uid Gid Size others;do
                let SumSize=SumSize+$Size;
        done;
        echo $SumSize 
)
#Подсчитать сумарный размер jpg-файлов в текущей папке
Пример интересный, но всё же лучше для этих целей использовать:
du -bc *.jpg | tail -n1
да лучше, но я хотел продемонстрировать связку «while read» на несложном для понимания примере — в bash_history ничего коротенького не нашел, поэтому придумывал на ходу.
а что значит?
eject -2

у меня сидюк закрывается на
eject -t
очепятка — у мен и сидюка нет — написал и не проверил
Для переключения привода лучше использовать «eject -T»
да, точно
Спасибо за статью.

В разделе:
Оператор цикла until

в примере исправьте while на until
Подправил недочёты. Спасибо за ваше внимание.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.