Запускающий скрипт для tinyproxy
Ставил я не так давно простой и легкий прокси-сервер tinyproxy, и с удивлением не обнаружил в комплекте запускающего (инициализационного) скрипта.
Что это за зверь такой, если кто не знает. Ко многим демонам в Linux в комплекте идет инициализационный скрипт, позволяющий демона запустить, "убить" или перезапустить из консоли командой вида daemonname start (stop, restart)
без необходимости вручную отлавливать идентификатор процесса, убивать его командой kill
и проверять, завершен ли процесс (или наоборот, стартовал ли он). К squid
, например, такой скрипт идет, называется (в Slackware) rc.squid
и лежит в /etc/rc.d
, а к tinyproxy
в комплекте не шло, но написать его оказалось не так и сложно.
Итак, скрипт будет получать из командной строки единственный параметр с командой:
start
- запускать прокси-сервер
stop
- останавливать его
restart
- перезапускать (останавливать, а после остановки запускать)
status
- отображать, запущен или не запущен прокси.
Определяем основные переменные
#!/bin/bash
PIDFILE="/home/provproxy/tinyproxy.pid"
TINYPROXYCMD="/usr/sbin/tinyproxy"
PIDVAL=0
WTIMEOUT=30
OK=0
CH_S[0]='-' #pseudographic items
CH_S[1]='/'
CH_S[2]='|'
CH_S[3]='\'
ITEM_ARR=0 #current item counter
PIDFILE
- переменная, в которой указан PID-файл, файл, содержащий идентификатор основного процесса прокси-сервера.
Tinyproxy
при запуске создает сразу несколько процессов, позволяющих ему распараллеливать свою внутреннюю работу. Минимальное и максимальное число таких процессов задается в конфигурационном файле
/etc/tinyproxy.conf
параметрами
MinSpareServers
и
MaxSpareServers
, а процесс, идентификатор которого указан в PID-файле основной, управляющий. Ему можно послать сигнал, например, командой
kill
, и все остальные процессы тоже завершатся.
Местоположение PID-файла также указывается в файле /etc/tinyproxy.conf
в параметре PidFile
. Конечно, правильнее читать сам конфигурационный файл, и выдергивать значение параметра оттуда, ну да ладно, параметр этот перенастраивается нечасто, посему пусть такое решение останется на моей совести -=^_^-=.
TINYPROXYCMD
- путь к исполняемому файлу прокси-сервера
PIDVAL
- здесь будет храниться значение PID, полученное из PID-файла.
WTIMEOUT
- максимальное время ожидания запуска
tinyproxy
, или его завершения.
OK
- флаг, принимающий значение 1 в случае успешного запуска/завершения, или 0 - в случае неуспеха. Вообще-то, можно и без него обойтись, но мне с ним удобнее и нагляднее.
CH_S[0] - CH_S[3]
, массив с псевдографическими элементами, для украшательства, отображения хода процесса запуска. Подробности про украшательства
тут или
тут , и если кому не надо, выбросить лишние команды из скрипта - дело нехитрое. Переменная
ITEM_ARR
предназначена для тех же целей.
Функции
Далее, определим в скрипте несколько функций.
( см. описание функций под катом )Проверка параметров.
Проверять параметры будем при помощи оператора
case
, после объявления функций.
case "$1" in
start)
start_proxy
;;
stop)
stop_proxy
;;
restart)
restart_proxy
;;
status)
status_proxy
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
Если первый параметр, переданный из командной строки
start, stop, restart
или
status
- выполняются соответствующие функции, если что-то еще (
*
) - выводим краткую справку по использованию скрипта. В списке источников в конце заметки есть ссылка на более подробное описание оператора.
Статус процесса
Получается функцией
process_status()
. Вот ее код:
#Получаем PID
if [ -e $PIDFILE ];then #если файл существует
PIDVAL=`cat $PIDFILE` #читаем PID
TMPGREP=`ps -p $PIDVAL|grep "tinyproxy" -c` #процесс запущен - 1 иначе 0
if [ $TMPGREP -ge 1 ];then #процесс запущен
return #выходим из функции
else #pid-файл есть, процесса нет
rm $PIDFILE #удаляем pid-файл
fi
fi
PIDVAL=0
Сначала проверяется наличие PID-файла, если он существует, отправляем его содержимое (конструкция ``), прочитанное с помощью команды
cat
в переменную
PIDVAL
, далее, запрашиваем информацию о процессе (
ps
) по его PID (ключ
-p
). Если процесс существует, команда
ps
отправит на стандартный вывод что-то типа:
PID TTY TIME CMD
2100 ? 00:00:00 tinyproxy
А если процесса не существует:
PID TTY TIME CMD
Далее, этот вывод передается команде
grep
, которая фильтрует строки с именем искомого процесса (
tinyproxy
) и подсчитывает их количество (ключ
-c
). Если строк 1 процесс с данным PID существует, если 0 - процесса нет.
Если PID-файл существует, то в переменной
$PIDVAL
остается идентификатор процесса и происходит выход из функции
[...]
if [ $TMPGREP -ge 1 ];then #процесс запущен
return #выходим из функции
[...]
Если PID-файл существует, а процесс с данным PID не обнаружен, значит в PID-файле указан не тот PID, что, в большинстве случаев, может произойти из-за падения программы (с tinyproxy это случается довольно редко), либо из-за общего системного сбоя вызванного, например, отключением питания. Поэтому стоит PID-файл удалить.
Если процесс не обнаружен, или PID-файл не найден, то происходит выход из всех условных конструкций и переменной
$PIDVAL
присваивается значение 0
[...]
PIDVAL=0
[...]
Таким образом, если процесс существует, то в переменной
$PIDVAL
будет присутствовать его идентификатор, если не существует - значение 0.
Примечание о безопасности и стабильности использования PID-файлов. Конечно, есть более универсальный способ найти процесс не обращаясь к PID-файлу, например, получить список процессов командой
ps ax
и отgrep'ать его, найдя нужное нам имя, и, если надо, то завершить его командой
pkill имя_процесса
, и данный способ весьма неплохо будет работать с тем же
tinyproxy
.
Но tinyproxy - это просто web-прокси сервер, и неизвестно, что произойдет, если применить такой метод, например, к серверу баз данных. Возможно, какие-то транзакции не завершатся, порушится сама база. Поэтому, информации, сохраняемой программами в PID-файлах, стоит доверять. Безопасность их использования и контроль доступа к ним других пользователей должны решаться другими средствами ОС. Посему я не вижу смысла загромождать скрипт дополнительными проверками.
За
пояснение благодарю
ketmarОтображение статуса tinyproxy
Если функция
process_status()
используется для получения статуса (и PID) процесса для внутренних целей скрипта, то функция
status_proxy()
выводит информацию пользователю. И хоть она очень проста, но лучше вынести ее отдельно, дабы не смешивать взаимодействие с пользователем со внутренней механикой программы.
Вот код этой функции:
status_proxy()
{
process_status
if [ $PIDVAL -eq 0 ]; then
echo "Tinyproxy not running"
else
echo "Tinyproxy running [PID=$PIDVAL]"
fi
}
Как я и говорил, функция очень проста, сначала вызывается функция
process_status
, и если в переменной
$PIDVAL
значение 0, то выводится сообщение о том, что tinyproxy не запущен, иначе, что запущен и дополнительно выводится его PID.
Запуск прокси-сервера
Выполняет его функция
start_proxy()
. Вот ее код:
( см. код и описание функции под катом )
ПРИМЕЧАНИЕ: Если прокси не запускается, то для поиска неисправности удобно запустить прокси-сервер с ключом
-d
tinyproxy -d
В таком случае прокси запустится не в виде фонового процесса (демона), а в виде обычного, и выдаст ошибки на консоль. Например, если на файерволе закрыты порты, необходимые серверу, будет выведено сообщение:
tinyproxy: Could not create listening socket.
Остановка прокси-сервера
За остановку прокси-сервера отвечает функция
stop_proxy()
. Ее код:
( см. код и описание функции под катом )Перезагрузка прокси-сервера.
Тут вообще все просто.
1. Запускаем функцию остановки
stop_proxy
.
2.
Сбрасываем флаг:
$OK=0
Выполняем функцию запуска
start_proxy
Вот нехитрый код функции
restart_proxy()
:
restart_proxy()
{
stop_proxy
OK=0
start_proxy
}
Скачать скрипт
С PastebinС Mega.nzСписок источников
1.
Bash. Функции.2.
Возврат значений из функции3.
Оператор case
4.
Tinyproxy 5.
Коды завершения, имеющие предопределенный смыслЭто репост заметки из моего блога на сайте http://tolik-punkoff.com
Оригинал заметки находится здесь: http://tolik-punkoff.com/2016/11/05/zapuskayushhij-skript-dlya-tinyproxy/