echo $count
count=$((count + 1))
done
echo "Finished."
С условным выражением $count -gt 5 команда until завершит цикл в нужный момент времени. Выбор между циклами while и until обычно зависит от того, в каком случае условное выражение будет более читабельным.
Команды while и until могут принимать данные со стандартного ввода. Это дает возможность обрабатывать файлы с их помощью. В следующем примере мы выведем содержимое файла distros.txt, созданного в одной из предыдущих глав:
#!/bin/bash
# while-read: чтение строк из файла
while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
$distro \
$version \
$release
done < distros.txt
Чтобы перенаправить файл в цикл, мы поместили оператор перенаправления после инструкции done. Цикл будет вводить поля из указанного файла с помощью read. После ввода каждой строки команда read будет завершаться с кодом 0, пока не достигнет конца файла. В этот момент она вернет ненулевой код завершения, и цикл завершится. Цикл можно также использовать в конвейерах:
#!/bin/bash
# while-read2: чтение строк из файла
sort -k 1,1 -k 2n distros.txt | while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
$distro \
$version \
$release
done
Здесь вывод команды sort передается на стандартный ввод цикла, который выводит поток текста на экран. Но не забывайте, что конвейер выполняет цикл в подоболочке, поэтому после его завершения любые переменные, созданные в цикле, будут потеряны.
После знакомства с циклами и ранее представленными командами ветвления, функциями и последовательностями мы получили представление об основных способах управления потоком выполнения в программах. В арсенале bash имеется еще множество хитрых трюков, но все они основаны на этих простых идеях.
30. Поиск и устранение ошибок
Поскольку наши сценарии становятся все сложнее и сложнее, настало время посмотреть, что случается, когда что-то идет не так и сценарии перестают делать то, что нам нужно. В этой главе мы познакомимся с некоторыми распространенными ошибками, встречающимися в сценариях, и приемами поиска и устранения неисправностей.
Один из самых распространенных видов ошибок — синтаксические ошибки. Синтаксические ошибки возникают при неправильном вводе некоторого элемента с нарушением синтаксиса командной оболочки. Чаще всего эти ошибки вызывают отказ командной оболочки от выполнения сценария.
Для демонстрации распространенных видов ошибок в дальнейших обсуждениях мы будем использовать следующий сценарий:
#!/bin/bash
# trouble: сценарий для демонстрации распространенных видов ошибок
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
В текущем своем виде сценарий выполняется без ошибок:
[me@linuxbox ~]$ trouble
Number is equal to 1.
Давайте изменим сценарий, удалив кавычку в конце аргумента первой команды echo:
#!/bin/bash
# trouble: сценарий для демонстрации распространенных видов ошибок
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1.
else
echo "Number is not equal to 1."
fi
Посмотрите, что из этого получилось:
[me@linuxbox ~]$ trouble
./trouble: строка 10: неожиданный EOF при поиске соответствующего `"'
./trouble: строка 13: ошибка синтаксиса: неожиданный конец файла
Командная оболочка сгенерировала два сообщения об ошибках. Обратите внимание, что номера строк в сообщениях не соответствуют номеру строки, где отсутствует кавычка. Понять причину можно, мысленно последовав за программой после отсутствующей кавычки. bash продолжит поиск закрывающей кавычки и найдет ее сразу за второй командой echo. После этого командная оболочка bash очень удивится, обнаружив нарушение синтаксиса команды if, потому что инструкция fi теперь окажется внутри строки в кавычках (незакрытой).
Найти такие ошибки в длинных сценариях порой очень сложно. Хорошую помощь в этом случае может оказать текстовый редактор с подсветкой синтаксиса. Если в системе установлена полная версия редактора vim, подсветка синтаксиса в нем включается командой:
:syntax on
Отсутствующие или неожиданные лексемы
Другая частая ошибка — отсутствие закрывающего элемента в составной команде, такой как if или while. Взгляните, что получится, если убрать точку с запятой после проверки условия в команде if.
#!/bin/bash
# trouble: сценарий для демонстрации распространенных видов ошибок
number=1
if [ $number = 1 ] then
echo "Number is equal to 1."
else
Читать дальше