LINUX.ORG.RU
решено ФорумAdmin

bash скрипт. Помогите правильно написать.


1

2

Здравствуйте уважаемые лорчане! Имеется скрипт, но хотелось бы узнать у профессионалов, правильно ли он написан. И еще одна штука не понятна, как его зациклить, чтоб он работал постоянно. К примеру, стартует система, крон вызывает скрипт, и скрипт работает постоянно. Т.е после завершения скрипта, чтоб он по второму кругу прокручивался, и так до бесконечности.

Собственно суть скрипта: Скрипт проверки доступности источника, если источник недоступен, блокировать доступ к нему и проверять доступность на протяжении некоторого времени. Если источник стал доступен, осуществить контрольную проверку доступности на протяжении некоторого времени, если все ок, то снять блокировку. Схема работы: Отправляем 3 пинга источнику, если источник не ответил на 3 пинга, блокируем доступ к источнику по iptables, создаем файл-флаг и возвращаемся вначало (опять 3 пинга) и так ожидаем до полного ответа на все 3 пинга. Если источник ответил на 3 пинга, проверяем наличие файл флага, если флага нету, то начинаем все сначала, если файл флаг присутствует, то пингуем еще 120 раз (прим 2 минуты) если 120пингов успешны, снимаем блокировку, если 120 пингов не успешны, то возвращаемся в начало.

Сам скрипт: (проверьте плиз на правильность по вышеописанному)

#!/bin/sh

# Доступность этого хоста будет означать корректную работу оснвного источника
HOST="217.117.21.169"

# Файл-флаг. Появляется при переключении на резервный канал
LOCKFILE="/tmp/check_source.lock"

# Файл журнала
LOGFILE="/var/log/check_source.log"

# Пингуем проверочный хост
ping -I 217.74.21.189 -c 3 -n -q ${HOST} > /dev/null

# Если возникла ошибка (хост не доступен)
if [ $? -ne "0" ]; then
        # Если нет файла-флага
        if [ ! -f ${LOCKFILE} ]; then
                # блокируем доступ по списку правил
                iptables-resotre < /opt/iptables.block
                # Создаём файл флаг
                touch ${LOCKFILE}
                # Делаем запись в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source blocked >> ${LOGFILE}
        fi
# Если же всё хорошо
else
        # Если есть файл-флаг
        if [ -f ${LOCKFILE} ]; then
                # Пингуем еще 120 раз, если пинги проходят удачно, убираем блокировку
                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
                # Удаляем файл-флаг
                rm -f ${LOCKFILE}
                # Записываем событие в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source deblocked >> ${LOGFILE}
        fi
fi

Ну, и собственно вопрос, как его зациклить....


Ну, и собственно вопрос, как его зациклить....

Вызывайте в cron с нужным вам интервалом времени, к примеру 2 минуты, либо используйте, к примеру цикл while:

while [ 1=1 ] 
do 
  echo 2 
done

kostik87 ★★★★★ ()
Ответ на: комментарий от kostik87

Вызывайте в cron с нужным вам интервалом времени

насколько я понял, крон ему не подходит.
2ТС: пихни всё в while, как тебе подсказал kostik.

dada ★★★★★ ()

Скрипты писать не умею, стыбзил с просторов интернета скрипт проверяющий аплинки (резервирование) ну и переделал его под свой лад. Т.е если я правильно понял, то сам скрипт с учетом моих переделок написан правильно? И чтоб зациклить, мне нужно добавить while в конец, после финализации «fi» Т.е скрипт будет выглядеть так.


#!/bin/sh

# Доступность этого хоста будет означать корректную работу оснвного источника
HOST="217.117.21.169"

# Файл-флаг. Появляется при переключении на резервный канал
LOCKFILE="/tmp/check_source.lock"

# Файл журнала
LOGFILE="/var/log/check_source.log"

# Пингуем проверочный хост
ping -I 217.74.21.189 -c 3 -n -q ${HOST} > /dev/null

# Если возникла ошибка (хост не доступен)
if [ $? -ne "0" ]; then
        # Если нет файла-флага
        if [ ! -f ${LOCKFILE} ]; then
                # блокируем доступ по списку правил
                iptables-resotre < /opt/iptables.block
                # Создаём файл флаг
                touch ${LOCKFILE}
                # Делаем запись в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source blocked >> ${LOGFILE}
        fi
# Если же всё хорошо
else
        # Если есть файл-флаг
        if [ -f ${LOCKFILE} ]; then
                # Пингуем еще 120 раз, если пинги проходят удачно, убираем блокировку
                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
                # Удаляем файл-флаг
                rm -f ${LOCKFILE}
                # Записываем событие в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source deblocked >> ${LOGFILE}
        fi
fi
while [ 1=1 ] 
do 
  echo 2 
done


Где не прав, прошу поправить :)

CeMKa ()
Ответ на: комментарий от CeMKa
#!/bin/sh

# Доступность этого хоста будет означать корректную работу оснвного источника
HOST="217.117.21.169"

# Файл-флаг. Появляется при переключении на резервный канал
LOCKFILE="/tmp/check_source.lock"

# Файл журнала
LOGFILE="/var/log/check_source.log"
while: 
do 
 
# Пингуем проверочный хост
ping -I 217.74.21.189 -c 3 -n -q ${HOST} > /dev/null

# Если возникла ошибка (хост не доступен)
if [ $? -ne "0" ]; then
        # Если нет файла-флага
        if [ ! -f ${LOCKFILE} ]; then
                # блокируем доступ по списку правил
                iptables-resotre < /opt/iptables.block
                # Создаём файл флаг
                touch ${LOCKFILE}
                # Делаем запись в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source blocked >> ${LOGFILE}
        fi
# Если же всё хорошо
else
        # Если есть файл-флаг
        if [ -f ${LOCKFILE} ]; then
                # Пингуем еще 120 раз, если пинги проходят удачно, убираем блокировку
                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
                # Удаляем файл-флаг
                rm -f ${LOCKFILE}
                # Записываем событие в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source deblocked >> ${LOGFILE}
        fi
fi
 
done
system-root ★★★★ ()
Ответ на: комментарий от system-root

Огромнейшее спасибо!! :) Задача решена. Всем еще раз спасибо за участие! )

CeMKa ()
Ответ на: комментарий от CeMKa

И чтоб зациклить, мне нужно добавить while в конец, после финализации «fi»

Ну а если подумать ? В цикле выполняется только тело цикла, т.е. част кода, которая находится между while ; do и done.

Т.е. в моём примере:

while :
do 
  echo 2 
done
телом цикла будет 'echo 2'.

Вам нужно поместить в цикл строки начиная с вызова ping и заканчивая fi.

kostik87 ★★★★★ ()
Ответ на: комментарий от kostik87

Благодарю, что разжевали. Сразу не допер что echo2 это пример тела цикла.

CeMKa ()
Ответ на: комментарий от snoopcat

это оправдано если

running=true
while [ $running = true ]
...
running=false
...
как например
  len = tempBuffer.readUInt8(pos)
while (len != 0){
  arr.push((tempBuffer.slice(pos + 1, pos + len + 1)).toString('ascii'))
  var pos = (len + pos + 1)
  var len = tempBuffer.readUInt8(pos)
		}
в других случаях это как-то.. по капитански смотрится что ли.

system-root ★★★★ ()
Последнее исправление: system-root (всего исправлений: 1)
Ответ на: комментарий от system-root

Хм, посидел почитал еще раз скрипт и походу нашел ошибку. В блоке:

# Если же всё хорошо
else
        # Если есть файл-флаг
        if [ -f ${LOCKFILE} ]; then
                # Пингуем еще 120 раз, если пинги проходят удачно, убираем блокировку
                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
                # Удаляем файл-флаг
                rm -f ${LOCKFILE}
                # Записываем событие в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source deblocked >> ${LOGFILE}
        fi
fi
 
done

Конкретно на действии

# Пингуем еще 120 раз, если пинги проходят удачно, убираем блокировку
                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
                # Удаляем файл-флаг
Если я правильно понимаю, то в этом действии, отправляется пинг 120раз и ЕСЛИ результат был нулевым = 0 (if [ $? -ne «0» ]; then) (пинги не прошли) то выполнить: iptables-restore < /opt/iptables.open

Верно? А мне какбэ надо, чтоб если 120пингов удачны, то продолжить дальше по условиям (iptables-restore < /opt/iptables.open), если 120 пингов не удачны, начать скрипт целиком заново(т.е как вначале отправить 3 пинга, если неудачны, то блокируем, если удачны идем дальше и пингуем еще 120раз.

Есть кто подмогнёт дописать правильно? )

CeMKa ()
Ответ на: комментарий от CeMKa

ЕСЛИ результат был нулевым = 0 (if [ $? -ne «0» ]; then) (пинги не прошли) то выполнить: iptables-restore < /opt/iptables.open

Нет, проверяется код ошибки, если код ошибки 0, то следовательно проблем не было и все пинги прошли.

Почитайте уже документацию по написания скриптов в Bash, например Advance Bash Scripting Guide. На http://www.opennet.ru есть русский вариант, да и просто в Internet полно переводов.

kostik87 ★★★★★ ()
Последнее исправление: kostik87 (всего исправлений: 1)
Ответ на: комментарий от CeMKa

я вообще считаю что долбить на чужой сервер пингом 24/7 это плохо.
пинг вообще может быть заблокирован, в конце концов тебя могут просто забанить даже провайдеры, потому что это нарушение договора использование сети.
по этому скажи:
1) чей это за сервер
2)какого рода сервис он тебе должен предоставлять
3) время реагирование на его падение
4) почему bash
5) почему блокировать его после падения?
потому что на лоре последнее время какие-то вопросы с условиями которые просто выносят мозг.
то подменить днс у машины в которой просто нет интернета, то банить фаерволлом упавший хост, то iscsi on mips..

system-root ★★★★ ()
Последнее исправление: system-root (всего исправлений: 2)
Ответ на: комментарий от kostik87

Если код ошибки 0, то проблем не было. Но ведь в этом условии так же стоит if [ $? -ne «0» ]; then и в этой части скрипта если 3 пинга НЕ прошло, то он проверяет файл-флаг и блокирует доступ.

# Пингуем проверочный хост
ping -I 217.74.21.189 -c 3 -n -q ${HOST} > /dev/null

# Если возникла ошибка (хост не доступен)
if [ $? -ne "0" ]; then
        # Если нет файла-флага
        if [ ! -f ${LOCKFILE} ]; then
                # блокируем доступ по списку правил
                iptables-resotre < /opt/iptables.block
                # Создаём файл флаг
                touch ${LOCKFILE}
                # Делаем запись в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source blocked >> ${LOGFILE}
        fi
# Если же всё хорошо

CeMKa ()
Ответ на: комментарий от CeMKa

Вот эта запись «[ $? -ne „0“ ]» эквивалентна записи «test $? -ne „0“».

TEST(1)                          User Commands                         TEST(1)



NAME
       test - check file types and compare values

SYNOPSIS
       test EXPRESSION
       test

       [ EXPRESSION ]
       [ ]
       [ OPTION

       ...

       STRING1 = STRING2
              the strings are equal

       STRING1 != STRING2
              the strings are not equal

       INTEGER1 -eq INTEGER2
              INTEGER1 is equal to INTEGER2

       INTEGER1 -ge INTEGER2
              INTEGER1 is greater than or equal to INTEGER2

       INTEGER1 -gt INTEGER2
              INTEGER1 is greater than INTEGER2

       INTEGER1 -le INTEGER2
              INTEGER1 is less than or equal to INTEGER2

       INTEGER1 -lt INTEGER2
              INTEGER1 is less than INTEGER2

       INTEGER1 -ne INTEGER2
              INTEGER1 is not equal to INTEGER2

В первом случае да, всё верно, если код ошибки не равен 0 нулю (пинг не дошёл), то блокируем доступ.

kostik87 ★★★★★ ()
Ответ на: комментарий от system-root

1)Хост который я пингую, это мой сервер на другом конце города. 2) Сервис рода: потоковое вещание звука. Т.е и на сервере№1 (пингующим) 2 провайдера и на сервере №2(который пингуем) тоже два провайдера. 3)Время реагирования: данный скрипт пингует другой сервак по внутренней сети общего провайдера №1, если в какой либо из точек упал провайдер №1 то необходимо шустро переключиться на 2го провайдера. Время дорого аж до нескольких секунд. 4)Почему баш? Другими способами не знаю как проверять доступность хоста. Единственное что лезет в голову, пинговать хост. 5) Почему блокировать после падения? Объясню: Сервер1-потребляет поток по двум првоайдерам Сервер2 - отдает поток по двум провайдерам серверу 1. Приоритетнее провайдер №1 второй только на случай аварии. К примеру ситуация, Идет потоковое вещание по провайдеру №1, все нормально, но вдруг провайдер 1 падает. Сервер-потребитель в течении 3-5 секунд автоматически переходит на резерв, на провайдер №2. Продолжает вещать. Тут вдруг провайдер№1 чинится, и становится доступным, сервер-потребитель видит что хост откуда забирать поток стал доступным по провайдеру №1 и автоматом в течении 3-5 секунд возвращается на него. Продолжает вещать. И вдруг провайдер №1 опять скатина падает. Опять же происходит переключение на провайдера №2. Тем самым появляются дыры в потоке на выхлопе. Просто были уже ситуации, когда первый провайдер пропадет, через минуту появится, после чего через несколько секунд опять пропадет, и опять же через несколько секунд появится и опять пропадет. И так на протяжении нескольких часов (авария у них там была)

Данным скриптом, я хочу чтобы, если провайдер №1 упал, автоматика перешла на резерв, и вещала на нем, и если вдруг появился провайдер №1, то сначала проконтролировать его нормальную работу, т.е погонять его канал несколько минут (сколько задумаю) и только после успешного прогона канала в течении нескольких минут, смело возвращать вещание на него. Вот в чем весь смысл.

CeMKa ()
Ответ на: комментарий от tazhate

В каком месте?

Абоненту запрещается блаблабла сканировать порты, рассылать какие нибудь пакеты, поднимать какие-нибудь службы и чтоб не мешать другим пользователям
что-то в этом роде даже я подписывал.
за over900 килобайт icmp трафика в месяц забанить могут.

system-root ★★★★ ()
Ответ на: комментарий от CeMKa

есть такая штука Bonding 2 канал в один, при падение одного из каналов работает резервный.
посмотри может это взлетит?

system-root ★★★★ ()
Ответ на: комментарий от system-root

Абоненту запрещается блаблабла сканировать порты, рассылать какие нибудь пакеты, поднимать какие-нибудь службы и чтоб не мешать другим пользователям

Рассылать какие-нибудь пакеты? А ничего, что ты прямо сейчас на 80ый порт лора пакеты послал?
Не неси чепуху, за ицмп куда угодно, даже без остановки, никто не блокирует. Скан сети тут никоим боком.

tazhate ★★★★★ ()
Последнее исправление: tazhate (всего исправлений: 1)
Ответ на: комментарий от tazhate

нене, могут в лёгкую icmp-flood в паять с конфискацией.
если подключался к акадо лет 5 назад может помнишь какие они упоротые, людей даже за mtu банят.
не не так:
людей даже за картинки банят =)

system-root ★★★★ ()
Ответ на: комментарий от system-root

если подключался к акадо лет 5 назад может помнишь какие они упоротые, людей даже за mtu банят.

У меня как раз он тогда и был, я правда ничего с сетью тогда не делал еще :)

tazhate ★★★★★ ()
Ответ на: комментарий от tazhate

как много ты потерял, на DOCSIS ты вообще в локалке /24 мог просто по виндовым шарам лазить и трафик по ssh прокидывать между разными абонентами.
The Dude вообще подвисал при построении карты локальной сети.
кстати ТС может вообще за одну из машин не платить если у него провайдер ещё из «машины времени»

system-root ★★★★ ()
Последнее исправление: system-root (всего исправлений: 1)
Ответ на: комментарий от system-root

кстати ТС может вообще за одну из машин не платить если у него провайдер ещё из «машины времени»

в цивилизованном мире, в 2013ом году, все провайдеры в ДС2 такие. Т.е. у нас можно сколько хочешь машин подключать к одному проводу. А вас мне жаль...

emulek ()
Ответ на: комментарий от emulek

Т.е. у нас можно сколько хочешь машин подключать к одному проводу

я имел ввиду, если у ТС 2 машины в разных концах города подключённые к одному провайдеру у которого локальная сеть есть, то одна из машин может работать шлюзом в интернет для трафика который перегонять по локалке провайдера бесплатно.

system-root ★★★★ ()

Продолжу тему: Скрипт всеравно нифига не пашет. Смысла отправлять меня гуглить мануалы по написанию скриптов bash нету, т.к это практически то же самое, что начать изучать его. Скажу сразу, скрипты сам писать не умею, в основном под нужную задачу ищется скрипт в инете, чуток модифицируется и после чего используется. Дальше по сути:..... Привожу опять кусок кода:

        # Если есть файл-флаг
        if [ -f ${LOCKFILE} ]; then
                # Пингуем еще 120 раз, если пинги проходят удачно, убираем блокировку
                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
                # Удаляем файл-флаг
                rm -f ${LOCKFILE}
                # Записываем событие в файл журнала
                echo `date +'%Y/%m/%d %H:%M:%S'` Source deblocked >> ${LOGFILE}
        fi
fi

конкретно на данном этапе:

                ping -I 217.74.21.189 -c 120 -n -q ${HOST} > /dev/null
		if [ $? -ne "0" ]; then
		iptables-restore < /opt/iptables.open
после 120 пингов, скрипту пофиг на результат, он тупо посылает 120 пингов, и не важно удачны они или нет, выполняет дальше действия. Т.е iptables-restore.

Прошу сильно не пинать. Обращаюсь конкретно с просьбой о помоши к башеписателям. Люди, помогите правильно дописать скрипт.

CeMKa ()
Ответ на: комментарий от CeMKa

Скажу сразу, скрипты сам писать не умею, в основном под нужную задачу ищется скрипт в инете, чуток модифицируется и после чего используется.

Берёте ручку и бумагу и пишете:

					Заявление.

Прошу уволить меня по собственному желанию по причине не соответствия занимаемой должности.

						Дата ________ 20__ года Подпись _______

Продолжу тему: Скрипт всеравно нифига не пашет. Смысла отправлять меня гуглить мануалы по написанию скриптов bash нету, т.к это практически то же самое, что начать изучать его.

Он и не будет «пахать» пока вы не разберётесь что и как работает. Направление поиска вам уже указали, читайте документацию по написанию скриптов в bash, Advanced Bash Scripting Guide.

kostik87 ★★★★★ ()
Последнее исправление: kostik87 (всего исправлений: 1)
Ответ на: комментарий от kostik87

По человечески попросил помочь дописать, а начался как обычно срачевник.... В итоге другие люди без проблем и быстренько помогли. Дописали две строки с условием «else» и все заработало как «задумывалось» и без всяких «выпендрежей» и изучением баша n=Времени.

Повторюсь, я не скриптописатель, не программист и не «красноглазик», поэтому в этом не имею опыта. Раз в столетку понадобилось, попросил помочь добрых людей. Добрые помогли, а вот «выпендрежи» как всегда начали в своем роде.
Всем участникам большое спасибо!! Проблема решена.

CeMKa ()
Ответ на: комментарий от CeMKa

Ну вот и выучили бы используемые конструкции в скрипте, что бы понять что в нём написано, а потом сами бы дописали ваши две строки, а не тратили бы время.

kostik87 ★★★★★ ()
Ответ на: комментарий от kostik87

Спасибо за совет. Конечно же рано или поздно, всеравно в жизни понадобится не раз. Поэтому и прийдется учить. Но в данном случае понадеялся на лор, т.к знаю, что тут оперативно решаются задачи. А мне какраз надо было оперативно. Всеравно всем спасибо :)

CeMKa ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.