Делаем интерактивный BASH скрипт для загрузки сайта

Введение

Здравствуйте! Эта программа - всего лишь интерактивный интерфейс к некоторым функциям WGET. Она написана на BASH и может помочь новичкам в освоении этого скриптового языка. Если вам она нужна для использования - смело идите в конец статьи и качайте архив. Сейчас я поэтапно разберу создание этого скрипта. В bash комментарии начинаются с символа #, кроме первой строчки.(первая строка скрипта НИКОГДА не должна содержать комментариев)

Выбор инструмента


Из заголовка понятно, что скрипт мы будем писать на BASH. Также определимся, что программа должна работать под GNU/Linux. Может, она и заработает под bsd/mac. Кто осмелится попробовать - пишите в комментариях. Теперь, наша задача определиться с инструментом для создания интерактивности. После небольшого гугления, в частности страницы на stackoverflow, мы находим четыре варианта:
  1. Zenity - требует X сервер, включена в большинство дистрибутивов Linux по-умолчанию.
  2. KDialog - инструмент от разработчиков KDE, использует Qt. Раньше я уже его использовал, но в Ubuntu 14.04 требуется установить пакет kde-baseapps-bin, который к тому же тянет ещё и кучу зависимостей.
  3. Использование стандартных echo/read
  4. Dialog - утилита идёт в комплекте поставки Ubuntu 14.04, не требует X сервера и, на мой вкус, приятно выглядит.
С kdialog я уже работал, хочется чего-то нового. Выбор пал (та-дамсс) на Dialog.

Пишем базовый код

Gedit/Ubuntu linux/код на bash
Создадим файл main.sh . В нём будет код нашей программы.
В начале любого bash скрипта должна быть строчка #!/bin/bash Сначала, надо выполнить проверку окружения, а именно проверить наличие dialog и bash в системе:
tput setaf 1 #В случае ошибки выведем её красным цветом
if ! [ -x "$(command -v dialog)" ] || ! [ -x "$(command -v wget)" ]; then
tput setaf 1
echo "error"
tput sgr0
exit 1
fi
tput sgr0 #Переключаем шрифт обратно
Хорошо, теперь можно приступать к написанию основной части программы. Конечно, скрипт работающий с сокетами и парсящий HTML на наличие ссылок, мы делать не будем. Мы воспользуемся возможностями wget, в частности загрузкой сайтов
Спросим URL сайта, предварительно прочитав вывод "dialog --help". Опция inputbox выведет диалог ввода строки. Нули задают автоматическую ширину и высоту окна.
URL=$(dialog --stdout --inputbox "Введите Url" 0 0)
Результат выполнения команды
Если пользователь нажал Cancel, то код ошибки ($?) будет равен единице. Сделаем проверку:
if [ $? == 1 ];
then
Echo "До свидания"
exit 1
fi
Теперь, нам надо узнать, хочет ли пользователь чтобы ресурсы, расположенные выше по уровню, загружались и по скольким ссылкам можно переходить:
np=""
l=$(dialog --stdout --no-cancel --inputbox "По скольким ссылкам переходить?" 0 0 2)
Результат выполнения команды
dialog --yesno "Переходить в каталоги выше?" 0 0
Результат выполнения команды
if [ $? == 1 ];
then
np=" --no-parent "
fi
Ну, и вызываем wget:
wget -U Mozilla -r -k -l $l -p -E $np $URL -q
Всё, база есть. Теперь добавим поддержку нескольких языков:

Мультиязычность


Вводим в google bash multilanguage, находим статью(перевод) приводим код к виду:

#Getting URL of the site to featch
URL=$(dialog --stdout --title $"title" --inputbox $"eURL" 0 0)
#Checking if user entered a URL
if [ $? == 1 ];
then
gettext -s "CBye"
exit 1
fi

#How much links to follow?
l=$(dialog --stdout --no-cancel --title $"title" --inputbox $"lynxnum" 0 0 2)
dialog --title $"title" --yesno $"parents" 0 0
if [ $? == 1 ];
then
np=" --no-parent "
fi
#robots=off
mkdir -p $DIRECTORY
tput setaf 2 #Green
echo Downloading...
tput setaf 1 #Wget output is red
wget -U Mozilla -r -k -l $l -p -E $np $URL --directory-prefix=$DIRECTORY -q # -o /dev/null #-nc
tput setaf 2 #Green
echo Done...
tput sgr0
exit $?


Создаём po файл:

msgid "title"
msgstr "Загрузчик сайтов"
msgid "CBye"
msgstr "Операция отменена! До свидания!"
msgid "lynxnum"
msgstr "По какому количеству ссылок переходить?"
msgid "parents"
msgstr "Переходить по ссылкам на другие домены?"
msgid "eURL"
msgstr "Введите адрес сайта, который хотите загрузить"
msgid "Cancel"
msgstr "Отмена"
msgid "dialog-error"
msgstr "Ошибка: команда dialog или команда wget не найдена в системе."


И ничего не работает... После долгого поиска ошибок, выясняем что автор статьи почему-то забыл сказать, что для работы требуется указать собственно имя po файла: TEXTDOMAIN=main.sh.(источник:opennet) Теперь всё работает! Для удобной подготовки переводов я написал такой скрипт:
#!/bin/bash
for FILENAME in *.po;
do
lang=$(echo $FILENAME | sed s/.po/""/)
echo processing $lang
mkdir -p ./lang/$lang/LC_MESSAGES/
msgfmt -o main.sh.mo $FILENAME
cp -p main.sh.mo ./lang/$lang/LC_MESSAGES/
done

Открытие файлов

Тут всё просто. Добавим немного кода для открытия уже загруженных страниц. Конечный код можно прочитать по ссылке:main.sh

Результат

Распространяется под лицензией GNU GPLv3. Архив здесь



🖶 💾 ?