Linux и UNIX: программирование в shell. Руководство разработчика
Шрифт:
$ pg whileorder2
#!/bin/sh
#whileorder2
#инициализация переменных
HOLD=order.tmp
RE_ORDER=0
ORDERS=0
STATIONERY_TOT=0
if [ -s $HOLD ]; then
echo "=========== STOCK RE_ORDER REPORT ================"
while read ITEM REORD LEVEL
do
#находимся ли мы ниже уровня переупорядочивания для данного пункта??
if [ "$LEVEL" — lt "$REORD" ]; then
да, выполняется заказ другого количества товаров
NEW_ORDER=`expr $REORD + $REORD`
# подсчет итогов по заказам
ORDERS=`expr $ORDERS + 1`
# подсчет итогов по уровням запасов
STATIONERY_TOT=`expr $STATIQNERY_TOT + $LEVEL`
echo "$ITEM need reordering to the amount $NEW_ORDER"
done <$HOLD
echo "$ORDERS new items need to be ordered"
echo "Our reorder total ls $STATIONERY_TOT"
else
echo "`basename $0` : Sorry $HOLD does not exist or ls empty"
fi
Результат выполнения сценария при обработке файла заказов.
$ whileorder
========= STOCK REORDER REPORT ===============
Pens need reordering to the amount 28
Pads need reordering to the amount 14
Disks need reordering to the amount 6
Sharpeners need reordering to the amount 10
4 new items need to be ordered
Our reorder total is 18
Не составляет особого труда скомбинировать два описанных сценария в один; в действительности изначально использовался один сценарий, который был разбит на два в учебных целях.
18.7.10. Цикл while и дескрипторы файлов
При изучении дескрипторов файлов в главе 5 уже упоминалось о том, что для считывания данных в файл применяется цикл while. С помощью дескрипторов файлов 3 и 4 следующий сценарий создает резервную копию файла myfile.txt под именем myfile.bak. Обратите внимание, что в начале сценария осуществляется проверка, которая позволяет убедиться в наличии файла. Если файл отсутствует или не содержит данные, выполнение сценария немедленно прекращается. Также обратите внимание на то, что в цикле while имеется команда null (:). Из-за наличия этой команды цикл может выполняться бесконечно, поскольку null всегда возвращает значение "истина". При осуществлении попытки считывания по достижении конца файла отображается сообщение об ошибке. При этом выполнение сценария прекращается.
$ pg copyfile
#!/bin/sh
# copyfile
FILENAME=myfile.txt
FILENAME_BAK=myfile.bak
if [ -s $FILENAME ]; then
#открыть FILENAME для записи
#открыть FILENAME для считывания'
exec 4>$FILENAME_BAK
exec 3<$FILENAME
#бесконечный цикл до тех пор, пока имеются данные или пока не возникает
#ошибка, связанная с достижением конца файла while :
do
read LINE <&3
if [ "$?" -ne 0 ]; then
# ошибки при закрытии
exec 3<&-
exec 4<&-
exit fi
# запись в файл FILENAME_BAK
echo $LINE>&4
done else
echo "`basename $0` : Sorry, $FILENAME is not present or is empty" >&2
fi
18.8. Управление ходом выполнения циклов с помощью команд break и continue
Иногда в процессе работы возникает необходимость в прерывании или пропуске отдельных итераций цикла. При этом применяются определенные критерии. Для обеспечения подобных возможностей интерпретатор shell предлагает две команды:
• break;
• continue.
18.8.1. Команда break
Команда break позволяет прервать выполнение цикла. Эта команда обычно'; используются для выхода из цикла или прекращения выполнения оператора case' после осуществления некоторой обработки. Если вы окажетесь внутри вложенного цикла, можно указать количество прерываемых циклов: например, если существуют два вложенных цикла, для их прерывания используется команда break 2.
18.8.2. Прекращение выполнения оператора case
Рассмотрим следующий пример. В сценарии выполняется бесконечный цикл до тех пор, пока пользователь не введет число, большее 5. Для прерывания цикла и возврата в командную строку интерпретатора используется команда break.
$ pg breakout
#!/bin/sh
• breakout
• while : бесконечный цикл while :
do
echo -n "Enter any number [1..5] :"
read ANS
case $ANS in
1|2|3|4|5) echo "great you entered a number between 1 and 5"
;;
*) echo "Wrong number..bye"
break
;;
esac
done
18.8.3. Команда continue
Команда continue по своему действию напоминает команду break, за исключением одной существенной детали: она не прерывает цикл, а лишь приводит к пропуску текущей итерации цикла.
18.8.4. Пропуск строк в файлах
Рассмотрим файл, содержащий перечень сотрудников. Этот файл уже использовался ранее, но теперь он будет включать некоторую заголовочную информацию.
$ pg names2.txt
LISTING OF PERSONNEL FILE
TAKEN AS AT 06/1999
Louise Conrad:Accounts:ACC8987
Peter James:Payroll:PR489
Fred Terms:Customer:CUS012
Janes Lenod:Accounts:ACC887
Frank Pavely:Payroll:PR4S9
При просмотре этого файла нетрудно заметить, что его первые две строки не содержат сведений о сотрудниках. Поэтому эти строки желательно исключить.
Также не следует принимать во внимание сведения о сотруднике с именем Peter
james Этот человек уволился из компании, но запись о нем осталась в файле.
Давайте все же сохраним заголовочную информацию, выполнив простой подсчет считываемых строк При этом обработка файла будет выполняться в том случае, когда номер строки будет больше двух Если строка содержит имя Peter James, она будет исключена из процесса обработки.
Вот сценарий, выполняющий описанные задачи
$ pg whilecontinue