LINUX.ORG.RU

Рекурсия в программах для мониторинга

 , , ,


0

2

Никак не мог найти себе подходящую программу для автоматической синхронизации файлов с сервером при их изменении, пришлось написать свою на bash. Вот ее активная часть:

while true; do
    if [[ -n $(git status -s) ]]; then 
        cd $1
        git add .
        git commit -m "Git commit `date +'%d.%m.%Y %H:%M:%S'`"
        git push origin master
        notify-send -i face-smile "Синхронизация выполнена"
    fi
done
Т.е программа постоянно смотрит вывод git status и если обнаружит, что файл изменен, она автоматически его коммитит. Работает идеально. Но я беспокоюсь за чистоту программирования и еще за сохранность моего жесткого диска. Она ведь постоянно долбится в этот git status, насколько это правильно? Можно было конечно не делать бесконечным циклом, а запускать по cron, но мне нужна именно моментальная синхронизация. С другой стороны, как устроены другие популярные программы для синхронизации или мониторинга чего-либо, типа Dropbox или Seafile? Я не разбирался, что у них происходит под капотом, может они тоже также долбятся в свое?
Расскажите пожалуйста об этом, если знаете, и может быть дадите какие-нибудь советы, как улучшить этот алгоритм?

★★★★★

Последнее исправление: Rinaldus (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

Rinaldus ★★★★★
() автор топика

синхронизации файлов ... git push origin master

наркоман. Наверное тебе был нужен fuse или nfs

mashina ★★★★★
()
Ответ на: комментарий от Rinaldus

git commit -m «Git commit `date +'%d.%m.%Y %H:%M:%S'`»

И как ты потом найдешь среди коммитов нужный и поймешь причину правок? По diff'у?

Вообще тебе нужно постоянно синхронизировать? Может какой-нибудь sleep стоит прикрутить? Или посмотреть в сторону того, чему ты изменяешь файлы - если это какой-нибудь vim\emacs то там можно (скорее всего, не пробовал) прикрутить чтоб коммит выполнялся при сохранении файла.

У Dropbox вроде fuse использовался, сейчас пропихивают что-то там в ядро в виде модуля (не в курсе приняли ли это или нет).

alozovskoy ★★★★★
()
Ответ на: комментарий от Rinaldus

Она к сожалению не умеет задать для мониторинга файлы определенных расширений.

А зачем?
В твоем случае пусть хоть что-то изменится в нужном тебе каталоге, а там ты уже будешь делать всякие $(git status -s). Всё же легче, чем постоянно поллить.

А бесконечный цикл - это очень плохо. Хоть sleep 3 сделай.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 2)

Гит долбится не в «свое», а в каждый stat/mtime как минимум, как максимум в diff с оригиналом из .git. Поскольку при таком поллинге метаданные и так в кеше, грузишь ты только проц. Поставь адекватный таймаут, например 1 — имхо достаточно моментально, учитывая время самого пуша.

В твоем решении кстати в гит могут залетать частичные сейвы и сейвы-ин-прогресс, не знаю плохо это или нет.

arturpub ★★
()

Рекурсия в программах для мониторинга

Тут нет никакой рекурсии

Никак не мог найти

Не искал.

Но я беспокоюсь за чистоту программирования

Беспокоился бы - не использовал бы башизмы

-if [[ -n $(git status -s) ]]; then
+if [ -n $(git status -s) ]; then 

Работает идеально

Оно racy, ты ещё не наступил или не заметил. Оно добавит в репозиторий временные файлы редактора и недозаписанные файлы в процессе записи.

и еще за сохранность моего жесткого диска

От чтения ещё никто не умирал, тем более оно всё всё равно в кэше. Вот то что эта помойка на 100% грузит одно ядро - это не дело. Хотя бы sleep 1 добавил.

С другой стороны, как устроены другие популярные программы

В системе есть API для слежения за изменениями файловой системы: ЕМНИП, inotify в linux и kqueue во FreeBSD. Есть библиотеки которые от этого API абстрагируются, gamin например. Во FreeBSD есть ещё libinotify, которая видимо просто предоставляет совместимое с linux API. Что-то из этого и используют.

slovazap ★★★★★
()
Ответ на: комментарий от Kroz

sleep 2 сделал.

А зачем?

Дело в том, что при открытии тех файлов, которые я редактирую, в той директории создается несколько временных файлов, которые присутствуют, пока редактор открыт и удаляются, когда он закрывается. Но exclude в этом inotifywait реализован через такое одно место, что мне выпилить ложные срабатывания так и не удалось. Указать файлы определенных расширений для слежки inotifywait тоже не позволяет. Вот и пришлось изобретать собственный велосипед.

Rinaldus ★★★★★
() автор топика
Ответ на: комментарий от Rinaldus

Но exclude в этом inotifywait реализован через такое одно место, что мне выпилить ложные срабатывания так и не удалось.

Так может наоборот передать ему полный список файлов, за которыми надо следить? Вроде такого (лучше директории, конечно, передавать, ну и событие нужное указать):

inotifywait --fromfile <(git ls-tree --name-only -r HEAD)

xaizek ★★★★★
()
Ответ на: комментарий от slovazap

Беспокоился бы - не использовал бы башизмы

Чавой?

-if [[ -n $(git status -s) ]]; then
+if [ -n $(git status -s) ]; then

Это чтоб жизнь медом не казалась, да?

Zmicier ★★★★★
()
Ответ на: комментарий от xaizek

Я уже пробовал ему скормить файл со списком отслеживаемых файлов и пробовал твоим способом - он вообще не реагирует на сигналы.

Rinaldus ★★★★★
() автор топика

Она ведь постоянно долбится в этот git status

Ничего себе, а как же plumbing там, всё такое, как же каркас для построения системы контроля версий под задачу, как же низкоуровневая версионированная файловая система на объедках Git, как же вековая мудрость вождя нашего?

d_a ★★★★★
()
Ответ на: комментарий от arturpub

Я их и сунул. А для чего мне троекратное срабатывание кода во время редактирования файла и естественно троекратное уведомление, что файл синхронизирован?

Rinaldus ★★★★★
() автор топика
Ответ на: комментарий от Rinaldus

А коммит часом не возвращает 1, если нечего коммитить? Или другой способ? Можно уведомление в if тогда сунуть.

И вообще почему статус возвращает тру, если они в игноре?

arturpub ★★
()
Ответ на: комментарий от arturpub

Какая разница, как этот статус отслеживать? Можно было бы и в if, но в любом случае эту конструкцию надо обернуть в бесконечный цикл, потому что в противном случае скрипт благополучно завершится и все.
«git status -s» ничего не возвращает в случае если нечего коммитить, т.е null

Rinaldus ★★★★★
() автор топика
Ответ на: комментарий от Rinaldus

Дело в том, что при открытии тех файлов, которые я редактирую, в той директории создается несколько временных файлов, которые присутствуют, пока редактор открыт и удаляются, когда он закрывается.

Всё равно вызовов будет меньше, чем, даже при sleep 2.
Ну, решать тебе.

Kroz ★★★★★
()
Ответ на: комментарий от Zmicier

Не использовать bash-специфичный синтаксис чтобы скрипт сломался на других шеллах? Странное у вас «чтобы жизнь мёдом не казалась». Но да, кавычки конечно нужно добавить.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

чтобы скрипт сломался на других шеллах?

Ага. И еще хорошо на Си++ не писать, чтоб программа не дай бог не «сломалась», когда вы ее компилятором Си будете собирать.

Странное у вас «чтобы жизнь мёдом не казалась».
Но да, кавычки конечно нужно добавить.

И однако забыли. А потом и еще про что-нибудь нужно будет не забыть, а потом еще про что-нибудь. Даешь любые лишения, лишь бы современными средствами не пользоваться!

По-моему, у меня с медом все в порядке.

И да, что значит «bash-специфичный»?

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.