Команда оболочки для запуска 'x' количество раз, пока команда продолжает терпеть неудачу - PullRequest
1 голос
/ 28 июня 2019

Я пытаюсь запустить команду оболочки (в настоящее время либо sh, либо bash), которая подключается к базе данных.Поскольку база данных все еще «прогревается», команда не выполняется.

Поэтому я пытался выполнить цикл (скажем, 100 попыток), и каждый раз, когда команда терпит неудачу, подождите 1 секунду и повторите попытку.

Если есть ошибка, это начало строки, которая выводится на стандартный вывод: Sqlcmd: Error: <snipped>

Вот что я пробовал:


for i in $(seq 1 100)
do
    X='/opt/mssql-tools/bin/sqlcmd -E -S localhost -Q "<some sql statement> "'
    if [[ $X == Sqlcmd: Error:* ]]
        echo "."
    then
        break
    fi
done

Это не работает, когда я выясняю, с чем сравнивать строки с помощью shell / bash ... но больше следил, чтобы я был на правильном пути и т. Д.

Ответы [ 2 ]

2 голосов
/ 28 июня 2019

Вы можете попробовать что-то вроде:

while true ; do
    if Sqlcmd xxx xxx xxx ; then break ; fi
    # or:
    Sqlcmd xx xxx xxx && break
    sleep 1
done

Вы также можете добавить счетчик:

for ((n=100;n>0;n--)) ; do
    Sqlcmd xxx xxx xxx
    if [[ $? == 0 ]] ; then
        break
    fi
    sleep 1
done
[[ $n == 0 ]] && echo Timeout && exit 1

Здесь я показываю два разных способа проверки возвращаемого значения, ноПервый вариант предпочтителен (if cmd ; then ... ; fi).

$? - это возвращаемое значение из последней команды, равное 0 после ее успешного завершения.Если он возвращает 0 даже в случае ошибки (которая может произойти для неправильно сформированных программ), вы можете проверить вывод с помощью grep:

Sqlcmd xxx xxx 2>&1 | grep <error pattern> > /dev/null
if [[ $? != 0 ]] ; then break ; fi

Здесь мы тестируем $? != 0, потому что grep будетвернуть 0 при обнаружении шаблона ошибки .

Если вы хотите получить результат вывода в переменную, выполните команду с X=$(Sqlcmd xxx xxx).Затем вы можете использовать сравнение строк bash:

X=$(Sqlcmd xxx xxx)
if [[ "$X" =~ .*error.* ]] ; then
    <handle error here>
fi

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

Вы также можете использоватьswitch/case конструкция:

case "$X" in
    *Error:*) echo " Error detected " ;;
    *) break ;;
esac

(обратите внимание на двойной ;;)

1 голос
/ 28 июня 2019

Я изучил все подсказки из сообщения @ matthieu .Вот что я в итоге сделал:

for i in $(seq 1 30)
do
    /opt/mssql-tools/bin/sqlcmd -U sa -P <snip> -S localhost -Q "USE Master" 2>&1

    if [[ $? != 0 ]]
    then
        # Failed
        echo "."
        sleep 1s
    else
        # worked!
        break
    fi
done

разбивка для тех, кто учится (как и я)

  • выполнить SQL-запрос с помощью команды sqlcmd.Любые ошибки через stderr (это 2 в 2>&1) будут перенаправлены на консоль stdout (это $1).REF: 2> & 1 идиома оболочки .
  • код состояния результата отправляется на $? (REF: что такое вопросительный знак bash доллара ?)
  • в случае неудачи (любое значение, НЕ являющееся нулем)потом поспите 1 сек и попробуем.Попытайтесь только 30 раз.
  • , если мы работали (значение равно нулю), тогда прекратите попытки и продолжайте ....

Так что у нас это есть!shell / bash shell 101 шт.удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...