Используйте дополнительное условие в моем цикле while в сценарии оболочки

Мы делаем частые развертывания, используя udeploy, и у нас есть сценарий оболочки для перезапуска http-сервера apache в качестве последней задачи. Скрипт прост: -

cd bin_path
sudo ./apachectl -k stop
sleep 5
sudo ./apachectl start
while [ $? -ne 0 ]
do 
    sudo ./apachectl start
    sleep 1
done

Теперь я хотел бы включить в этот цикл while дополнительное условие, которое проверяет определенное значение переменной счетчика, чтобы попытка перезапуска сервера была ограничена, скажем, 5 раз. Теперь вот что я хочу.

var = 0
sudo ./apachectl start
while [ $? -ne 0 -o $var lte 5 ]
do
    var = $((var+1))
    sudo ./apachectl start
    sleep 1
done

Но почему-то я не эксперт в синтаксисе сценариев оболочки. Если кто-то может помочь мне исправить сценарий для достижения желаемого решения.


person Ashley    schedule 30.08.2016    source источник
comment
убери пробелы var=0   -  person Diego Torres Milano    schedule 30.08.2016
comment
хорошо, так что var=0 и что-то еще, например, lte как -lte или sa var=$((var+1)   -  person Ashley    schedule 30.08.2016
comment
Обе петли while имеют проблему. Когда цикл повторяется, $? будет статусом команды sleep 1, а не sudo.   -  person Barmar    schedule 30.08.2016
comment
Вы должны использовать while sudo ./apachectl start; do.   -  person Barmar    schedule 30.08.2016
comment
не могли бы вы более четко указать последовательность, как использовать это, пока здесь, я сбит с толку, когда вы говорите, пока sudo ./apachectl start;do   -  person Ashley    schedule 30.08.2016


Ответы (2)


У вас несколько проблем.

  1. В назначениях переменных оболочки нет пробелов вокруг =.
  2. Ваш цикл while проверяет состояние sleep, а не sudo.
  3. Вы используете or вместо того, чтобы использовать and для объединения условий.
  4. Сравнения в test нуждаются в префиксе -.

Правильный сценарий должен быть:

var=0
while ! sudo ./apachectl start && [ $var -le 5 ]
do
    var=$((var+1))
    sleep 1
done
person Barmar    schedule 30.08.2016
comment
Привет, Бармар, я не эксперт по синтаксису оболочки, но просто общий вопрос, как работает while! sudo ./apachectl start work, я имею в виду даже не в фигурных скобках, а также здесь мы не проверяем статус выхода команды запуска, также я думаю, что это должно быть -le вместо -lte, правильно - person Ashley; 31.08.2016
comment
while command проверяет статус выхода команды. Помещение ! перед командой инвертирует статус выхода. В фигурных скобках нет необходимости, это просто конкретная команда, которая используется для проверки значений строк и чисел. - person Barmar; 31.08.2016
comment
на самом деле я не хочу запускать start 5 раз, я просто хочу попытаться запустить его максимум 5 раз, если он запускается с 1-й попытки, это хорошо, но не должен превышать максимум 5. Также я думаю, что && оператор или заставит оба условия, поэтому я думаю, что здесь должно быть ||, правильно, чтобы при попытках запустить сервер не более 5 раз, если он запускается с 2 попыток, это хорошо - person Ashley; 31.08.2016
comment
Оператор ! имеет более высокий приоритет, чем оператор &&, поэтому он отменяет только статус sudo. Так что я уверен, что это сделает то, что вы хотите. Он остановится, как только apachectl преуспеет или вы достигнете 5 попыток. - person Barmar; 31.08.2016
comment
или, я думаю, лучше всего будет var = 0 sudo ./apachectl start while [ $? -ne 0 -o $var lte 5 ] do sleep 1 var = $((var+1)) sudo ./apachectl start done done - person Ashley; 31.08.2016
comment
OP, хотя и использует конструкции while, на самом деле пытается запуститься хотя бы один раз перед циклом. Я предлагаю использовать конструкцию until. - person alvits; 31.08.2016
comment
@ Эшли - если вы считаете, что это лучше всего, вы должны сами ответить и описать, почему это лучше всего. - person alvits; 31.08.2016
comment
Это нормально, я имею в виду, что попыток может быть шесть, никаких проблем нет, просто хотел проверить, все ли в порядке, в противном случае я бы также попробовал вариант Бармара, как только я попробовал этот. - person Ashley; 31.08.2016
comment
@alvits Нет причин начинать до цикла. Цикл будет запущен apachectl start, и в случае успеха он завершит цикл. - person Barmar; 31.08.2016
comment
В вашем решении это не обязательно. Я комментировал общую конструкцию, о которой просил ОП, и конструкцию, которую он предлагает. - person alvits; 31.08.2016
comment
@Barmar: - Приносим извинения за неправильное понимание вашего сценария. Сценарий синтаксически и логически верен, и я протестировал его с различными командами, а не с запуском apachectl, просто чтобы убедиться, как он работает, и, честно говоря, я чувствую, что, основываясь на моих требованиях, вы старались изо всех сил предоставить решение на основе сценария. Но на самом деле у меня другая проблема, связанная с перезагрузкой моего сервера, и я не знаю, как решить эту проблему или как выполнить проверку этого условия с помощью сценария, потому что для этого требуются знания сценариев сервера, а я в этом не эксперт. Что ж, спасибо. за ваши старания :) - person Ashley; 01.09.2016

«Исправление» сценария кажется бесполезным занятием, когда однострочный «перезапуск apachectl» выполняет то же самое.

person covener    schedule 30.08.2016
comment
Добавьте к этому, когда apache не запускается из-за неудачного развертывания, имеет ли вообще смысл повторять попытку 5 раз? - person alvits; 31.08.2016
comment
Я имею в виду, что иногда для остановки требуется немного времени, поэтому просто нужно продолжать пытаться запустить его с некоторым количеством попыток, но определенно не в течение бесконечного периода времени. - person Ashley; 31.08.2016