Цикл через вывод докера, пока я не найду строку в bash

Я новичок в bash (почти никакого опыта), и мне нужна помощь с bash-скриптом.

Я использую docker-compose для создания нескольких контейнеров — например, 2 контейнера. 2-й контейнер выполнит команду bash, но перед этим мне нужно проверить, что 1-й контейнер исправен и полностью настроен. Вместо использования команды sleep я хочу создать сценарий bash, который будет расположен во втором контейнере, и после выполнения выполните следующие действия:

  1. Выполнить команду и записать вывод консоли в файл
  2. Прочитайте этот файл и проверьте, присутствует ли строка. Команда, которую я выполню на предыдущем шаге, займет несколько секунд (5–10) секунд, и мне нужно прочитать файл после того, как он завершит выполнение. Я полагаю, я могу добавить сон, чтобы убедиться, что команда завершена, или есть лучший способ сделать это?
  3. Если строка отсутствует, я хочу снова выполнить ту же команду, пока не найду строку, которую ищу.
  4. Как только я найду строку, которую ищу, я хочу выйти из цикла и выполнить другую команду

Я узнал, как это сделать на Java, но если мне нужно сделать это в сценарии bash.

В докер-контейнерах в качестве операционной системы используется alpine, но я обновил Dockerfile, чтобы установить bash.

Я попробовал это решение, но оно не работает.

#!/bin/bash

[command to be executed] > allout.txt 2>&1

until 
  tail -n 0 -F /path/to/file | \
  while read LINE
  do
    if echo "$LINE" | grep -q $string
    then
      echo -e "$string found in the console output"
  fi
  done
do
    echo "String is not present. Executing command again"
    sleep 5
    [command to be executed] > allout.txt 2>&1
done

echo -e "String is found"

person andrei1986    schedule 29.12.2019    source источник
comment
Конечно. В пункте 3 - нужно перечитывать весь файл или нет? Другими словами, искомая строка будет добавлена ​​к файлу или файл будет усечен?   -  person KamilCuk    schedule 29.12.2019
comment
В идеале, если строка не найдена, после повторного выполнения команды я хотел бы удалить исходный вывод консоли, записать новый вывод консоли и искать строку только в новом выводе.   -  person andrei1986    schedule 29.12.2019
comment
Я повторяюсь. Узнав, что искомая строка не найдена в файле, в пункте 3. При следующем поиске строки в файле. Вам нужно сканировать весь файл на наличие искомой строки или искомая строка будет добавлена ​​к файлу, поэтому вам нужно сканировать только новые данные, добавленные в файл? Как вывод консоли связан с тем, что вы ищете? Что модифицирует файл?   -  person KamilCuk    schedule 29.12.2019
comment
Не добавлено и не усечено. Как только строка найдена в файле, я хочу выйти из цикла.   -  person andrei1986    schedule 29.12.2019


Ответы (2)


Просто:

while :; do
   # 1. Execute a command and log the console output in a file
   command > output.log
   # TODO: handle errors, etc.
   # 2. Read that file and check if a String is present.
   if grep -q "searched_string" output.log; then
       # Once I find the string I am looking for I want to exit the loop
       break;
   fi
   # 3. If the string is not present I want to execute the same command again until I find the String I am looking for
   # add ex. sleep 0.1 for the loop to delay a little bit, not to use 100% cpu
done
# ...and execute a different command
different_command

Вы можете прервать выполнение команды с помощью timeout.

Заметки:

  • двоеточие — это утилита, возвращающая нулевой статус выхода, как true, я предпочитаю while : вместо while true, они означают одно и то же.
  • Представленный код должен работать в любой оболочке posix.
person KamilCuk    schedule 29.12.2019

В файле docker-compose используйте параметр depends_on.

depends_on позаботится о последовательности запуска и завершения работы ваших нескольких контейнеров.

Но он не проверяет готовность контейнера перед переходом к запуску другого контейнера. Чтобы справиться с этим сценарием, проверьте это.

Как описано в этой ссылке,

  • Вы можете использовать такие инструменты, как wait-for-it, dockerize или sh-совместимый ждать. Это небольшие скрипты-оболочки, которые вы можете включить в образ вашего приложения для опроса заданного хоста и порта до тех пор, пока он не начнет принимать TCP-соединения.

OR

  • В качестве альтернативы напишите свой собственный сценарий-оболочку, чтобы выполнить более специфическую проверку работоспособности приложения.

Если вы не хотите использовать вышеуказанные инструменты, проверьте это вне. Здесь используется комбинация HEALTHCHECK и service_healthy как показано здесь . Для полного примера проверьте это.

person mchawre    schedule 29.12.2019
comment
Большое спасибо за эти предложения. - person andrei1986; 29.12.2019