Запускайте 2 терминала одновременно. Выполняет команду в первом только после того, как второй выводит текст X

#linux #bash #terminal #sh

#linux #bash #терминал #sh

Вопрос:

У нас есть следующий вариант использования:

  1. Запустите команду (стороннюю, не контролирующую исходный код), которая запускает сервер разработки со встроенным «наблюдателем за файлами», который перекомпилирует исходные файлы и перезапускает сервер при обнаружении изменений в файлах (и публикует выходные данные в папке /dist только в самые последние секунды ~ 30-секундного процесса; папка /dist создается как последний шаг процесса публикации).
  2. Запустите вторичную команду «постобработки», которая должна выполняться только тогда, когда предыдущая команда успешно запустила сервер и опубликовала файлы в папке / dist (эта команда публикует некоторые дополнительные статические файлы в папке / dist, поэтому это зависит от существования папки).

При таком подходе возникает несколько проблем:

  • Команда с шага 1 «крадет» терминал, что означает, что он никогда не завершается (из-за file watcher). Таким образом, выполнение двух команд последовательно не является вариантом.
  • Вторая команда должна дождаться, пока терминал 1 выведет определенную строку (например, «Сервер запущен»), что означает, что папка /dist теперь готова. Только тогда это должно вступить в силу.

На данный момент мы ввели разумный режим «ожидания» в начале второго терминала, просто чтобы он ожидал, пока первая команда выполнит публикацию и папка /dist будет существовать. Проблема в том, что на более медленных компьютерах этого периода ожидания недостаточно (вторая команда начинает выполняться до того, как у первой было достаточно времени для создания папки /dist). На быстрых компьютерах первая команда завершается довольно быстро, и перед запуском второй команды требуется довольно неудобное время ожидания. Для целей разработки это очень раздражает.

Есть ли способ автоматизировать этот двухэтапный процесс?

Перефразируя:

Есть ли способ создать терминал X, запустить вторичный терминал Y и дождаться, пока терминал Y выведет определенную строку, прежде чем выполнять какое-либо действие. И предпочтительно выполнять это же действие, когда терминал Y выводит указанную строку снова и снова.

Мы предпочитаем решение для Windows, если это возможно, но Linux также является вариантом, если решение не найдено.

Комментарии:

1. Если вы ищете решение для Windows, почему вы не пометили этот вопрос как Windows ?

2. В окне Linux я должен использовать inotifywait команду для обнаружения создания каталога /dist .

Ответ №1:

Этот ответ предназначен для решения Linux;

Итак, часть первая: автоматический запуск двух терминалов. Нужно ли, чтобы терминалы, после того как они автоматизированы, действительно были видны кому-либо? Если нет, я бы запустил их на экранах. screen Команда позволяет создавать виртуальные терминалы, которые можно подключать и отсоединять по мере необходимости. Чтобы автоматически запустить экран с запущенной командой, используйте

 screen -S meaningful_service_name -d -m ./ ProcessA
  

Здесь «-S» задает название экрана на что-то понятное человеку, на что можно ссылаться позже, а «-d -m» означает запустить экран в отключенном режиме (идеально подходит для сценариев запуска) и запустить в нем следующую команду. Эти экраны будут работать в фоновом режиме (пока программы не завершатся или что-то не уничтожит их), и могут быть подключены с терминала пользователем с screen -r meaningful_service_name Затем пользователь может отключиться, нажав Ctrl-A, а затем D. Это также позволяет вам удаленно отслеживать процессы через SSH.

Что приводит ко второй части: Запуск ProcessB только после вывода A на экран. Экран позволяет нам делать так называемые «скриншоты» его текущего вывода. Это сохраняется как текстовый файл, поскольку (виртуальный) терминал основан на тексте.

 screen -S meaningful_service_name -p 0 -X hardcopy /some/file/location.txt
  

Здесь «-p» указывает, каким по сути является текущее окно (которое обычно должно быть равно нулю), а «-X» означает выполнение следующей команды. Теперь, когда у вас есть текстовый файл с выводом ProcessA, вы можете искать в нем, как в любом другом текстовом файле.

 #!/bin/bash
while true; do
screen -S meaningful_service_name -p 0 -X hardcopy /some/file/location.txt
if [[ $(cat /some/file/location.txt | grep "ProcessA's Output" | wc -l) -ge 1 ]]
then
break
fi
sleep 2
done
./ ProcessB