Отслеживайте папку на наличие изменений и запускайте команду при обнаружении изменения

10

Существует ли простой способ автоматического запуска команды (Терминал) при каждом изменении файла в определенной папке?

Это должно быть возможно через командную строку или встроенное приложение системы, без сторонних приложений.

Любые идеи?

Луи Б.
источник

Ответы:

6

Сохраните список свойств следующим образом ~/Library/LaunchAgents/test.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test</string>
    <key>ProgramArguments</key>
    <array>
        <string>say</string>
        <string>yy</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>~/Desktop/</string>
    </array>
</dict>
</plist>

Агент может быть загружен с помощью launchctl load ~/Library/LaunchAgents/test.plistили выхода из системы и обратно. Для внесения изменений требуется выгрузка и загрузка plist.

Расширение Tilde ( ~/) работает в WatchPaths по умолчанию. EnableGlobbing добавляет подстановочные знаки и расширения тильды для ProgramArguments, но это не влияет на Program или WatchPaths.

Если отслеживаемый файл изменяется в течение десяти секунд после последнего вызова, подобное сообщение добавляется в system.log:

com.apple.launchd.peruser.501[146]: (test) Throttling respawn: Will start in 7 seconds

Один из способов избавиться от сообщений - добавить что-то вроде sleep 10конца скриптов. Установка ThrottleInterval в 10 не помогает.

Изменения в подпапках просматриваемых папок не обнаружены.

Смотрите man launchdи man launchd.plistдля получения дополнительной информации.

LRI
источник
5

entr (1) - это утилита для запуска команд при изменении файлов. Он читает список файлов на STDIN и использует kqueue (2), чтобы избежать опроса.

Пример:

ls my_project/*.html | entr echo "file changed"
eradman
источник
3

Вы можете использовать действия с папками, которые позволяют выполнять сценарии (Automator) при изменении содержимого папки. Насколько я знаю, в Automator есть шаблон, который позволяет легко создать новое действие папки и прикрепить его к нужной папке. А добавив действие «Run Shell Script», вы должны просто получить желаемый эффект.

xeophin
источник
5
Спасибо, но похоже, что «Действия с папкой» запускаются только при добавлении файла в папку, а не при проверке существующего файла.
Луи Б.
3

Действия с папками подходят для запуска при добавлении или изменении файла.

Однако, если ваше определение измененного включает удаление файла, действия с папкой OSX не определяют, был ли файл удален.

Чтобы ответить на вопрос:

  1. Загрузите зависимости FileWatcher отсюда: https://github.com/eonist/swift-utils

  2. Познакомьтесь с командой swift в командной строке: http://krakendev.io/blog/scripting-in-swift

  3. Используйте этот код для просмотра папки.

Код:

var fileWatcher = FileWatcher(["~/Desktop/test/".tildePath])/*<---the fileWatcher instance must be scoped to your class*/

fileWatcher!.event = { event in
    Swift.print(self?.someVariable)//Outputs: a variable in your current class
    Swift.print(event.description)//Outputs: a description of the file change
}
eonist
источник
1

Automator имеет тип рабочего процесса, называемого «Папка-действие», который автоматически запускается при добавлении чего-либо в папку. Создайте его, затем используйте действие «Run Shell Script».

Тимоти Мюллер-Хардер
источник
4
Спасибо, но похоже, что «Действия с папкой» запускаются только при добавлении файла в папку, а не при проверке существующего файла.
Луи Б.
Ох, ну ладно. Сожалею.
Тимоти Мюллер-Хардер
0

Вы можете попробовать что-то вроде этого:

touch /tmp/dirb.tmp
while true do 
  ls /thedirtocheck > /tmp/dira.tmp 
  diff /tmp/dira.tmp /tmp/dirb.tmp || echo "something changed" 
  cp /tmp/dira.tmp /tmp/dirb.tmp 
  sleep 100 
done
Хольгер фон Амельн
источник
Вам нужно, по крайней мере, ls -lтакже отследить изменения файла.
холме
правильно .... пропустил это
Хольгер фон Амельн