Відстежуйте папку щодо змін та виконуйте команду, коли виявляється зміна


10

Чи існує простий спосіб автоматичного виконання команди (Terminal) щоразу, коли файл змінюється в певній папці?

Це повинно бути можливим за допомогою командного рядка або вбудованого в систему додатка, без сторонніх додатків.

Будь-які ідеї?



Відповіді:


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або виходити з системи та повертатися назад. Застосування змін вимагає вивантаження та завантаження списку.

Розширення ~/Tilde ( ) працює за замовчуванням у WatchPaths. EnableGlobbing додає підстановку підказки та розширення для аргументів ProgramArgents, але це не впливає на програму чи стежки спостереження.

Якщо переглянутий файл буде змінено протягом десяти секунд після останнього виклику, до 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для отримання додаткової інформації.


6

entr (1) - це утиліта для запуску команд при зміні файлів. Він читає список файлів на STDIN і використовує kqueue (2), щоб уникнути опитування.

Приклад:

ls my_project/*.html | entr echo "file changed"

3

Ви можете використовувати дії "Папка", які дозволяють виконувати (Автоматизатор) сценарії кожного разу, коли вміст у папці змінюється. Наскільки мені відомо, у Automator є шаблон, який дозволяє легко створити нову дію папки та приєднати її до потрібної папки. І додавши дії "Запустити скрипт оболонки", ви просто повинні отримати бажаний ефект.


5
Дякую, але виявляється, що "Дії папок" спрацьовують лише тоді, коли файл додається до папки, а не тоді, коли перевіряється існуючий файл.
Луї Б.

3

Дії папок добре спрацьовують, коли файл додається чи змінюється.

Однак якщо ваше визначення зміненого типу включає видалення файлу, дії папки OSX не визначають, чи було видалено файл.

Щоб відповісти на запитання:

  1. Завантажте залежність FileWatcher тут: https://github.com/eonist/swift-utils

  2. Ознайомте себе з швидким запуском в командному рядку: 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
}

1

Автоматизатор має тип робочого процесу під назвою "Дія папки", який автоматично запускається, коли щось додано в папку. Створіть його, а потім скористайтеся дією "Запустити сценарій оболонки".


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також вловлювати зміни файлів.
nohillside

правда .... пропустив це
Холгер фон Амельн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.