Запуск сценария
Запуская сценарий (как показано в листинге 1.15), введите в командной строке дату в формате месяц-день-год. Месяц можно указать в виде трехсимвольного сокращения, полного названия или числа; год должен состоять из четырех цифр.
Результаты
Листинг 1.15. Тестирование сценария valid-date
$ valid-date august 3 1960
Valid date: Aug 3 1960
$ valid-date 9 31 2001
valid-date: bad day value: Sep doesn’t have 31 days.
$ valid-date feb 29 2004
Valid date: Feb 29 2004
$ valid-date feb 29 2014
valid-date: 2014 is not a leap year, so Feb doesn’t have 29 days.
Усовершенствование сценария
Подход, аналогичный используемому в этом сценарии, можно применить для проверки значения времени в 24-часовом формате или в 12-часовом формате с суффиксом AM/PM (Ante Meridiem/Post Meridiem — пополуночи/пополудни). Разбив значение времени по двоеточиям, нужно убедиться, что число минут и секунд (если указано) находится в диапазоне от 0 до 59, и затем проверить первое поле на вхождение в диапазон от 0 до 12, если присутствует суффикс AM/PM, или от 0 до 24, если предполагается 24-часовой формат. К счастью, несмотря на существование секунд координации (високосных секунд) и других небольших корректировок, помогающих сохранить сбалансированность календарного времени, их можно игнорировать в повседневной работе, то есть нет необходимости использовать замысловатые вычисления.
При наличии доступа к GNU-команде date в Unix или GNU/Linux можно использовать совершенно иной способ проверки високосных лет. Попробуйте выполнить следующую команду и посмотрите, что получится:
$ date −d 12/31/1996 +%j
Если у вас в системе используется новейшая, улучшенная версия date, вы получите результат 366. Более старая версия просто пожалуется на ошибочный формат входных данных. Теперь подумайте о результате, возвращаемом новейшей командой date. Сможете ли вы написать двухстрочную функцию, проверяющую високосный год?
Наконец, данный сценарий слишком терпимо относится к названиям месяцев, например, название febmama будет опознано как допустимое, потому что инструкция case в строке проверяет только первые три буквы. Эту проблему можно устранить, организовав точную проверку общепринятых сокращений (таких как feb) и полных названий месяцев (february), и даже некоторых типичных опечаток (febuary). Все это легко реализуется, было бы желание!
№ 8. Улучшение некачественных реализаций echo
Как упоминалось в разделе «Что такое POSIX?» в начале этой главе, большинство современных реализаций Unix и GNU/Linux включают команду echo, поддерживающую флаг −n, который подавляет вывод символа перевода строки в конце, но такая поддержка имеется не во всех реализациях. Некоторые для подавления поведения по умолчанию используют специальный символ \c, другие просто добавляют символ перевода строки, не давая никакой возможности изменить это поведение.
Выяснить, какая реализация echo используется в текущей системе, довольно просто: введите следующие команды и посмотрите, что из этого получится:
$ echo −n "The rain in Spain"; echo " falls mainly on the Plain"
Если команда echo поддерживает флаг −n, вы увидите следующий вывод:
The rain in Spain falls mainly on the Plain
Если нет, вывод будет иметь следующий вид:
-n The rain in Spain
falls mainly on the Plain
Гарантировать определенный формат вывода очень важно, и эта важность будет расти с увеличением интерактивности сценариев. Так что мы напишем альтернативную версию echo, с именем echon, которая всегда будет подавлять вывод завершающего символа перевода строки. Благодаря этому мы получим достаточно надежный инструмент, который сможем использовать, когда понадобится функциональность echo −n.
Код
Способов исправить проблему с командой echo так же много, как страниц в этой книге. Но больше всего нам нравится очень компактная реализация, которая просто фильтрует ввод с помощью команды awk printf, как показано в листинге 1.16.
Листинг 1.16. Простая альтернатива echo, использующая команду awk printf
echon()
{
··echo "$*" | awk '{ printf "%s", $0 }'