Как выполнить команду при обновлении содержимого каталога?

27

Существует каталог A, содержимое которого часто меняется другими людьми.

Я сделал личный каталог, Bгде я храню все файлы, которые когда-либо были A.

В настоящее время я просто запускаю время, rsyncчтобы получить файлы для резервного копирования из Aв B. Однако я боюсь, что некоторые файлы будут добавлены A, а затем удалены, Aпрежде чем я получу возможность скопировать их B.

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

oadams
источник

Ответы:

29

Если у вас установлены inotify-tools, вы можете использовать inotifywaitдля запуска действия, если файл или каталог записаны в:

#!/bin/sh
dir1=/path/to/A/
while inotifywait -qqre modify "$dir1"; do
    /run/backup/to/B 
done

Когда -qqкоммутатор полностью бесшумен, -rрекурсивен (если необходимо) и -eявляется событием, которое нужно отслеживать, в этом случае modify. От man inotifywait:

изменить
Наблюдаемый файл или файл в наблюдаемом каталоге был записан.
jasonwryan
источник
5
incrondтакже может представлять интерес.
Шон Дж. Гофф
1
Круто. Могу ли я просто поместить вышеупомянутый скрипт в мой bashrc, чтобы он запускался при входе в систему? Есть ли другой способ, которым я могу запустить его все время?
oadams
Для входа, да /etc/profileдля всей системы или .bash_profileтолько для вашего пользователя. Чтобы запустить его после загрузки, это зависит от вашего вкуса Unix / Linux; /etc/rc.local, /etc/rc.d/Или/etc/init.d/
jasonwryan
1
Для более крупных каталогов вы можете рассмотреть возможность использования --monitorкоммутатора (и вместо этого перенаправить вывод в ваш цикл), в противном случае возникают большие издержки при inotifywaitповторном
запуске
Насколько надежно будет работать это решение для запуска сценария для каждого файла, который был добавлен в дерево каталогов через FTP-сервер (скажем, новый файл добавляется в среднем каждые 3 минуты, и это может продолжаться годами)? Если не очень, есть ли альтернативное решение?
Никола Новак
5

Строго говоря, если кто-то уронит файл и очень быстро удалит его, вы можете пропустить его. Использование inotify (в Linux или аналогичной функции в других приложениях) делает окно риска небольшим.

Если вы можете смонтировать файловую систему по вашему выбору в этот каталог (я понимаю, что это может быть не вариант), вы можете установить такую, которая будет записывать все версии файлов, например, copyfs .

Жиль "ТАК - перестань быть злым"
источник
4

Попробуйте entrинструмент командной строки, который может запускать произвольные команды при изменении файлов. Начиная с версии 2.9, -dбыла добавлена опция просмотра каталога ( ), чтобы реагировать на события, когда в каталог добавлялся новый файл.

Пример запуска утилиты, если в проект добавлен новый файл:

$ while true; do
> echo src/* | entr -d your_command
> done

В режиме просмотра каталогов родительский каталог каждого файла неявно добавляется в список наблюдения.

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

Вот версия без опции просмотра каталога:

$ while true; do
> echo src/* src | entr your_command
> done

Вот более простой пример в зависимости от ваших потребностей:

$ ls -d * | entr sh -c 'rsync -vuar A B'

Проверьте: entrproject.org веб-сайт для более подробной информации.

kenorb
источник