Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Название:Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Автор:
- Жанр:
- Издательство:Питер
- Год:2017
- Город:СПб.
- ISBN:978-5-496-03029-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание краткое содержание
Цель этой книги — продемонстрировать практические приемы программирования сценариев на bash и познакомить с самыми распространенными утилитами на коротких и компактных примерах, не вдаваясь в излишние подробности. Экспериментируйте с этими сценариями — ломайте, исправляйте и приспосабливайте их под свои нужды, чтобы понять, как они работают. Только так вы сможете решать самые сложные задачи.
Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
······exit 1
····fi
····date="$(normalize $word1)"
··else
····if [-z "$word2"]; then
······echo "Bad dayname format: unknown day name specified" >&2
······exit 1
····fi
····if [! -z "$(echo $word1|sed 's/[[: digit: ]]//g')"]; then
······echo "Bad date format: please specify day first, by day number" >&2
········exit 1
····fi
····if ["$word1" −lt 1 −o "$word1" −gt 31]; then
······echo "Bad date format: day number can only be in range 1-31" >&2
······exit 1
····fi
····if [! isMonthName $word2]; then
······echo "Bad date format: unknown month name specified." >&2
······exit 1
····fi
····word2="$(normalize $word2)"
····if [-z "$word3"]; then
······date="$word1$word2"
····else
······if [! -z "$(echo $word3|sed 's/[[: digit: ]]//g')"]; then
········echo "Bad date format: third field should be year." >&2
········exit 1
······elif [$word3 −lt 2000 −o $word3 −gt 2500]; then
········echo "Bad date format: year value should be 2000–2500" >&2
········exit 1
······fi
······date="$word1$word2$word3"
····fi
··fi
··/bin/echo −n "One-line description: "
··read description
··# Данные готовы к записи в файл
··echo "$(echo $date|sed 's/ //g')|$description" >> $agendafile
··exit 0
Второй сценарий, в листинге 3.13, короче, но используется чаще.
Листинг 3.13.Сценарий agenda, сопутствующий сценарию addagenda из листинга 3.12
··#!/bin/sh
··# agenda — сканирует файл. agenda в поисках записей, относящихся
··#·· к текущей дате
··agendafile="$HOME/.agenda"
··checkDate()
··{
····# Создать значения по умолчанию для сопоставления с текущей датой.
····weekday=$1 day=$2 month=$3 year=$4
····format1="$weekday" format2="$day$month" format3="$day$month$year"
····# И выполнить поиск среди записей в файле…
····IFS="|" # Команда read автоматически разбивает
············#·· прочитанные строки по символам в IFS.
····echo "On the agenda for today: "
····while read date description; do
······if ["$date" = "$format1" −o "$date" = "$format2" −o \
·········· "$date" = "$format3"]
······then
········echo " $description"
······fi
····done < $agendafile
··}
··if [! -e $agendafile]; then
····echo "$0: You don't seem to have an.agenda file. " >&2
····echo "To remedy this, please use 'addagenda' to add events" >&2
····exit 1
··fi
··# Получить текущую дату…
··eval $(date '+weekday="%a" month="%b" day="%e" year="%G"')
··day="$(echo $day|sed 's/ //g’)" # Удалить возможные пробелы в начале.
··checkDate $weekday $day $month $year
··exit 0
Как это работает
Сценарии addagenda и agenda поддерживают три типа событий: еженедельные («каждую среду»), ежегодные («каждого 3 августа») и однократные («1 января 2017»). В процессе добавления записей в файл событий их даты нормализуются и сжимаются так, что 3 August превращается в 3Aug, а Thursday превращается в Thu. Эта операция выполняется функцией normalize в сценарии addagenda .
Данная функция отсекает все, что следует за третьим символом, и преобразует первый символ в верхний регистр, а два остальных — в нижний. Такой формат соответствует стандартным сокращенным названиям дней недели и месяцев в выводе команды date, что необходимо для правильной работы сценария agenda. Остальная часть сценария addagenda не содержит ничего сложного; бо́льшую его часть занимает проверка формата введенных данных.
Наконец, в строке , он сохраняет нормализованные данные в скрытый файл. Отношение кода, связанного с проверкой ошибок, к коду, выполняющему фактическую работу, довольно типично для хорошо написанных программ: проверка и первичная обработка входных данных позволят сделать уверенные предположения об их формате в последующих приложениях.
Сценарий agenda проверяет события, преобразуя текущую дату в три возможных строковых представления ( день недели, число+месяц и день+месяц+год ) . Затем он сравнивает каждую из этих строк с датами из записей в файле .agenda . Найденные совпадения выводятся на экран.
Самый, пожалуй, интересный прием в этой паре сценариев — использование команды eval для присваивания четырем переменным четырех значений, определяющих дату :
eval $(date "+weekday=\"%a\" month=\"%b\" day=\"%e\" year=\"%G\"")
Можно было бы получить значения по одному (например, weekday="$(date +%a)"), но в очень редких случаях этот способ дает ошибочные результаты, если в ходе выполнения четырех вызовов date произойдет смена даты, так что краткая форма с единственным вызовом предпочтительнее. Плюс, это просто круто выглядит.
Так как date может вернуть день как число с нежелательным начальным пробелом, следующая строка удаляет его. А теперь посмотрим, как все это работает!
Запуск сценария
Сценарий addagenda предлагает пользователю ввести дату нового события. Затем, если дата имеет допустимый формат, сценарий предлагает ввести однострочное описание события.
Сопутствующий сценарий agenda не имеет параметров и, когда вызывается, выводит список всех событий, запланированных на текущую дату.
Результаты
Чтобы увидеть, как работает эта пара сценариев, добавим несколько новых событий, как показано в листинге 3.14.
Листинг 3.14.Тестирование сценария addagenda и добавление нескольких событий
$ addagenda
Agenda: The Unix Reminder Service
Date of event (day mon, day month year, or dayname): 31 October
One-line description: Halloween
$ addagenda
Agenda: The Unix Reminder Service
Date of event (day mon, day month year, or dayname): 30 March
One-line description: Penultimate day of March
$ addagenda
Agenda: The Unix Reminder Service
Date of event (day mon, day month year, or dayname): Sunday
One-line description: sleep late (hopefully)
$ addagenda
Agenda: The Unix Reminder Service
Date of event (day mon, day month year, or dayname): march 30 17
Bad date format: please specify day first, by day number
$ addagenda
Agenda: The Unix Reminder Service
Date of event (day mon, day month year, or dayname): 30 march 2017
One-line description: Check in with Steve about dinner
Теперь с помощью сценария agenda можно быстро вспомнить, что должно произойти сегодня, как показано в листинге 3.15.
Листинг 3.15.Использование сценария agenda для поиска событий на сегодня
$ agenda
On the agenda for today:
··Penultimate day of March
··sleep late (hopefully)
··Check in with Steve about dinner
Обратите внимание, что даты в совпавших событиях представлены в форматах: день недели, число+месяц и день+месяц+год . Для полноты картины в листинге 3.16 показано содержимое файла .agenda со всеми дополнительными записями:
Читать дальшеИнтервал:
Закладка: