Запуская сценарий, достаточно передать ему почтовый индекс, как показано в листинге 7.13. Очень просто!
Листинг 7.13.Тестирование сценария weather
$ weather 78727
Austin, TX (78727): Current temp 59.0F and Clear outside.
$ weather 80304
Boulder, CO (80304): Current temp 59.2F and Clear outside.
$ weather 10010
New York, NY (10010): Current temp 68.7F and Clear outside.
Усовершенствование сценария
Откроем небольшой секрет. В действительности этот сценарий принимает не только почтовые индексы. Службе Wunderground API можно также передать название региона, например CA/San_Francisco (попробуйте передать эту строку сценарию weather!). Однако такой формат не очень удобен: он требует использовать символы подчеркивания вместо пробелов и символ слеша (/) в середине. В качестве одного из усовершенствований можно было бы добавить в сценарий запрос на ввод аббревиатуры штата и названия города и автоматически заменять пробелы символами подчеркивания, если сценарий запущен без аргумента. Как обычно, можно также добавить дополнительную проверку ошибок. Например, что получится, если передать сценарию четырехзначный или недействительный почтовый индекс?
№ 59. Поиск информации о кинофильме в базе IMDb
Сценарий в листинге 7.14 демонстрирует более сложный пример доступа к Интернету с помощью lynx для поиска в базе данных Internet Movie Database ( http://www.imdb.com/) сведений о кинофильмах по указанному шаблону. База данных IMDb назначает уникальный числовой код каждому фильму, каждому телевизионному сериалу и даже каждой отдельной серии; если пользователь укажет такой код, данный сценарий вернет краткое описание фильма. В противном случае он вернет список фильмов, частично или полностью соответствующих указанному названию.
В зависимости от типа запроса (числовой код или название) сценарий обращается по разным адресам URL и сохраняет результаты в кэше, чтобы многократно обойти содержимое страницы для извлечения разных фрагментов информации. Для этого используется много — очень много! — вызовов команд sed и grep, в чем вы можете убедиться лично.
Листинг 7.14.Сценарий moviedata
··#!/bin/bash
··# moviedata — получая название фильма или сериала, возвращает список
··#·· совпадений. Если пользователь укажет числовой код IMDb, вернет
··#·· краткое описание фильма. Использует базу данных Internet Movie Database.
··titleurl="http://www.imdb.com/title/tt"
··imdburl="http://www.imdb.com/find?s=tt&exact=true&ref_=fn_tt_ex&q="
··tempout="/tmp/moviedata.$$"
··summarize_film()
··{
····# Форматирует описания фильма.
····grep "
····grep −color=never −A2 '
Plot:' $tempout | tail -1 | \
······cut −d\< −f1 | fmt | sed 's/^/ /'
····exit 0
··}
··trap "rm −f $tempout" 0 1 15
··if [$# −eq 0]; then
····echo "Usage: $0 {movie title | movie ID}" >&2
····exit 1
··fi
··#########
··# Выяснить тип запроса: по названию или по коду IMDb
··nodigits="$(echo $1 | sed 's/[[: digit: ]]*//g')"
··if [$# −eq 1 −a — z "$nodigits"]; then
····lynx −source "$titleurl$1/combined" > $tempout
····summarize_film
····exit 0
··fi
··##########
··# Это не код IMDb, поэтому нужно выполнить поиск…
··fixedname="$(echo $@ | tr ' ' '+')" # для формирования URL
··url="$imdburl$fixedname"
··lynx −source $imdburl$fixedname > $tempout
··# Нет результатов?
··fail="$(grep −color=never '
No ' $tempout)"
··# Если найдено несколько похожих названий…
··if [! -z "$fail"]; then
····echo "Failed: no results found for $1"
····exit 1
··elif [! -z "$(grep '
Displaying' $tempout)"]; then
····grep −color=never '/title/tt' $tempout | \
····sed 's/</\
····grep −vE '(.png|.jpg|>[]*$)' | \
····grep −A 1 "a href=" | \
····grep −v '^-$' | \
····sed 's/····awk '(NR % 2 == 1) { title=$0 } (NR % 2 == 0) { print title " " $0 }' | \
····sed 's/\/.*>/: /' | \
····sort
··fi
··exit 0
Этот сценарий конструирует разные адреса URL, в зависимости от содержимого аргумента. Если пользователь указал числовой код, сценарий конструирует соответствующий URL, загружает с помощью lynx сведения о фильме, сохраняет их в файле $tempout
и затем вызывает функцию summarize_film()
. Ничего сложного.
Читать дальше