ftp −np << EOF
open $server
user ftp $anonpass
cd $destdir
put "$filename"
quit
EOF
Для доступа к защищенной паролем учетной записи на сервере FTP можно добавить в сценарий запрос пароля в интерактивном режиме, отключив эхо-вывод перед инструкцией read, и включить его снова после ввода:
/bin/echo −n "Password for ${user}: "
stty −echo
read password
stty echo
echo ""
Однако самый грамотный способ организовать ввод пароля — позволить программе FTP самой предложить ввести его, что в нашем сценарии произойдет автоматически: если для доступа к указанной учетной записи потребуется пароль, программа FTP сама предложит сделать это.
№ 54. Извлечение адресов URL из веб-страницы
Простейшее применение lynx заключается в извлечении списка адресов URL, находящихся в данной веб-странице, что может пригодиться при поиске ссылок в Интернете. Выше мы говорили, что в этом издании книги предпочли уйти от lynx в сторону curl, но, как оказывается, lynx в сто раз удобнее для решения этой задачи (см. листинг 7.4), чем curl, потому что автоматически анализирует разметку HTML, тогда как curl вынуждает вас делать это вручную.
В вашей системе нет программы lynx? Большинство современных систем Unix снабжается диспетчерами пакетов, такими как yum в Red Hat, apt в Debian и brew в OS X (впрочем, brew не устанавливается по умолчанию), с помощью которых можно установить lynx. Если вы решите скомпилировать lynx самостоятельно или пожелаете загрузить скомпилированные двоичные файлы, вы найдете все необходимое по адресу: http://lynx.browser.org/.
Листинг 7.4.Сценарий getlinks
#!/bin/bash
# getlinks — получая URL, возвращает все относительные и абсолютные ссылки.
#·· Принимает три параметра: −d генерирует первичные домены в каждой ссылке,
#·· −i выводит список только внутренних ссылок на сайт (то есть на другие
#·· страницы на том же сайте), и −x выводит список только внешних ссылок
#·· (в противоположность −i).
if [$# −eq 0]; then
··echo "Usage: $0 [-d|-i|-x] url" >&2
··echo "-d=domains only, −i=internal refs only, −x=external only" >&2
··exit 1
fi
if [$# −gt 1]; then
··case "$1" in
····-d) lastcmd="cut −f— f3|sort|uniq"
········ shift
········;;
····-r) basedomain="http://$(echo $2 | cut −d/ −f3)/"
········lastcmd="grep \"^$basedomain\"|sed \"s|$basedomain||g\"|sort|uniq"
········shift
········;;
····-a) basedomain="http://$(echo $2 | cut −d/ −f3)/"
········lastcmd="grep −v \"^$basedomain\"|sort|uniq"
········shift
········;;
···· *) echo "$0: unknown option specified: $1" >&2
········exit 1
··esac
else
··lastcmd="sort|uniq"
fi
lynx −dump "$1"|\
··sed −n '/^References$/,$p'|\
··grep −E '[[: digit: ]]+\.'|\
··awk '{print $2}'|\
··cut −d\? -f1 |\
··eval $lastcmd
exit 0
Отображая страницу, lynx отображает ее текст, стремясь сохранить форматирование как можно ближе к оригиналу, а также список всех гипертекстовых ссылок, найденных на этой странице. Данный сценарий извлекает только ссылки с использованием команды sed для вывода всего, что следует за строкой «References» (Ссылки) в тексте веб-страницы
. Затем сценарий обрабатывает полученный список, как определено флагами, заданными пользователями.
Этот сценарий демонстрирует один интересный прием: настройку переменной lastcmd (
,
,
,
) для фильтрации списка ссылок в соответствии с флагами, заданными пользователем. После настройки переменной lastcmd применяется удивительно удобная команда eval
, чтобы заставить командную оболочку интерпретировать содержимое переменной как команду, а не как значение.
По умолчанию сценарий выводит список всех ссылок, найденных на указанной веб-странице, и не только тех, которые начинаются с префикса http:. Сценарию может быть передано три необязательных флага, влияющих на результат: флаг −d требует выводить только доменные имена в совпавших адресах URL, флаг −r требует оставить в списке только относительные ссылки (то есть указывающие на другие страницы на том же сервере, откуда получена текущая страница), и флаг −a требует вывести только абсолютные ссылки (то есть указывающие на другие серверы).
Читать дальше