Выполнять периодическую задачу с помощью команды BASH и смотреть

Я пытаюсь написать сценарий BASH с целью использования команды watch для мониторинга локального репозитория git на предмет изменений из удаленной ветки, а затем exe резка задачи.

Допустим, сценарий называется task.sh и выглядит так:

watch -n 3000 (git remote update && git status) | \
grep -i "your branch is behind origin/" && \ 
{ "pull changes, run tests, etc." ; }

То, что я опубликовал, примерно соответствует тому, что у меня есть до сих пор, но я не могу получить последнюю часть работать. Другими словами, кажется, что это не срабатывает, когда я вносил изменения в ветку git.Мне удалось перенаправить вывод из часов в такой файл watch -n 3000 ls 1 >> file.txt , но для использования этого метода потребуется открыть файл, который, как мне кажется работает медленно и подвержен ошибкам.

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

0
04.05.2017, 05:44
1 ответ

Как упомянул DopeGhoti, cron был бы гораздо лучшим выбором для этого.

В вашем примере уже есть 50-минутный интервал. Если допустим интервал в час, во многих современных дистрибутивах есть каталог /etc/cron.hourly. Все в этом каталоге с установленным исполняемым битом будет запускаться ежечасно (большинство реализаций, которые я видел, используют run-parts , которые запускают исполняемые файлы в этом каталоге линейно по имени файла).

Если необходим более короткий интервал, я бы рекомендовал /etc/cron.d. Демон cron обычно анализирует этот каталог напрямую, поэтому нет необходимости устанавливать исполняемый бит. Вы можете создать файл с именем task со следующим содержимым.

*/30 * * * * root /path/to/task.sh

Первые 5 полей предназначены для минуты, часа, дня месяца, месяца и дня недели. В этом случае мы даем минуту значение шага 30 минут. Итак, этот конкретный пример будет запускать task.sh каждые 30 минут, каждый час, каждый день месяца, каждый... ну вы поняли.

Значения шага более 30 минут в поле минут приводят к выполнению в N минут после часа, где N — значение в поле минут.

См. здесь одно решение для нечетных интервалов.

Теперь перейдем к коду bash...

Причина, по которой это не работает должным образом, заключается в том, что grep никогда не возвращает значение выхода, которое должно быть оценено &&. Он по-прежнему grep обрабатывает вывод watch.

Это можно увидеть на следующем примере.echo и sleep в фигурных скобках заменяют watch. После выхода sleep grep тоже может. Вторая дата не запускается до тех пор, пока grep не выйдет, и код выхода не может быть оценен.

[vagrant@localhost ~]$ date +%s; { echo a; sleep 15; } | grep 'a' && date +%s
1493875975
a
1493875990

Один из способов исправить это — переместить все в пределах наблюдателей.

watch -n 15 'bash -c "echo a | grep 'a' && date +%s"'

Другой вариант — использовать цикл while-true.

[vagrant@localhost ~]$ while :; do echo a | grep 'a' && date +%s; sleep 15; done
a
1493875992
a
1493876007
a
1493876022
^C
1
28.01.2020, 02:46

Теги

Похожие вопросы