CGI приложение на базе shell-скрипта. Где это еще может быть актуально

в 10:16, , рубрики: cgi, dd-wrt, Беспроводные технологии, Настройка Linux, ненормальное программирование

Доброго времени суток, хабрачитатели!

Появился у меня уже относительно давно роутер, ASUS RT-N10U. Всем он мне нравился, и захотелось мне с ним поиграться. Прошил его dd-wrt-шкой, понастраивал там все, как мне хотелось. И решил поднять на нем веб-сервер, так как имел полтора десятка книг в HTML-е и планшет, с которого их достаточно удобно читать (как оказалось в последствии). И тут я столкнулся с не очень приятной штукой. Заливать книжки на роутер в общем-то не сложно: закинул по ftp, переместил куда надо — и все тут. А вот добираться до них из браузера потом своеобразно.

Сначала у меня был index.html (с ссылками на все, что там у меня есть), который я честно правил руками. Поначалу мне этого хватало, но потом, когда книжки начали добавляться интенсивнее, решил, что надо что-то менять в жизни. Ставить PHP на роутер или кучу добра для кросскомпиляции на десктоп, из-за одной веб-страницы мне не хотелось, и я решил написать CGI-ку shell-скриптом.

Преимущества и недостатки

Ну, собственно, преимущество одно — не нужно захламлять бедный роутер лишними вещами. Тут все ясно. Но есть один существенный минус: shell-скрипты, в качестве cgi — это «слегка» тормознуто. По-этому, если вы захотите сделать что-то большое (или не только для зайти_два_раза_в_день), то этот хак — не для вас. Предупредил — теперь можно и по сути писать.

Основная идея

Последовательность действий довольно простая:

  1. Ищем все html-ки, которые лежат в папке и подпапках (у каждого это свое место; у меня книжки лежат в /opt/share/www/literature/...)
  2. Для каждой найденой страницы получаем относительный путь к ней (ссылку в браузер)
  3. Вытаскиваем у страниц содержимое тега title, которое мы дальше будем использовать в качестве идентификатора страницы. Тут многие могут сделать иначе — зависит от количества веб-страниц и их содержимого.
    Важно! Если вы согласны с третьим пунктом, то кодировки всех страниц должны быть одинаковыми (у меня везде UTF-8), так как в противном случае у вас появятся карлюки для не английского текста.

Собственно код

Начинается все, как всегда в shell-скриптах:

#!/bin/sh

Дальше пишем функцию, которая печатает информацию о том, что возвращает наша CGI:

print_cgi_info() {                    
        echo "Content-Type: text/html"
        echo "Cache-Control: no-cache"
        echo "Pragma: no-cache"                                                             
        echo ""                                                                             
}

Теперь функцию, которая найдет нам список html-страниц в папке. Паттерн "*.htm*" для поиска страниц наверное не очень, но так как у меня есть страницы и .html, и .htm, то я использую его. У вас может быть просто ".html":

get_list_of_book() {                                                                      
        listOfBook=$(find /opt/share/www/literature/ -type f -name "*.htm*" -print | sort)
}

Пишем функцию, которая вытаскивает из веб-страницы значение title. Подразумевается, что оно лежит в первых 10 строках файла:

get_title_from_web_page() {           
        pageTitle=$(head -n 10 "$1" | grep "<title>" | sed 's/.*<title>//; s/</title>.*//')
}

Функция, которая делает нам относительную ссылку из пути к веб-странице:

get_href_from_path() {                                                                      
        pageRef=$(echo "$1" | sed 's//opt/share/www//')                                  
}

Ну и теперь, собственно, главная часть нашего скрипта:

print_cgi_info

echo "<html>"
echo "  <head>"
echo "    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">"
echo "    <title>A little shelf with books</title>"
echo "  </head>"
echo "  <body>"

get_list_of_book
for book in $listOfBook; do
        get_href_from_path $book
        get_title_from_web_page $book
        echo "    <a href="$pageRef">$pageTitle</a><br>"
done

echo "  </body>"
echo "</html>"

Последние приготовления

Сохраняем теперь этот скрипт под названием index.cgi там, где его найдет наш роутерный веб-сервер. Делаем ему:

chmod +x index.cgi

Вроде все.

Надеюсь, что статья будет для многих начинающих dd-wrt-юзеров полезной, так как проблема, как мне кажется, довольно распространенная.

Автор: Nabytovych

Источник


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js