Чи є на Mac така команда, як "дивитися" або "inotifywait"?


287

Я хочу переглянути папку на своєму Mac (Snow Leopard), а потім виконати скрипт (надавши йому ім'я файлу того, що щойно переміщено в папку (як параметр ... x.sh "ім'я файлу")).

У мене є сценарій, написаний у bash (x.sh), який переміщуватиме деякі файли та інші речі на вході $ 1. Мені просто потрібен OSX, щоб дати мені ім'я файлу, коли нові файли / папки переміщуються / створюються у dir.

Якась така команда?


1
Вам слід запитати, як це робить DropBox, оскільки, імовірно, вони спробували всі доступні варіанти.
Джефф Берджес

2
@JeffBurdges Я не дуже впевнений, що це було б легким починанням. Однак я б сказав, що після прошивки над Apple FSEvents Reference було б дуже глупо, якби Dropbox не використовував це. fswatchUtil представлений як відповідь нижче робить фактично використовувати цей метод.
Стівен Лу

Відповіді:


447

fswatch

fswatch - це невелика програма, що використовує API Mac OS X FSEvents для контролю каталогу. Коли приймається подія про будь-яку зміну цього каталогу, вказана команда оболонки виконується/bin/bash

Якщо ви користуєтеся GNU / Linux, inotifywatch (частина inotify-toolsпакету більшості дистрибутивів) забезпечує аналогічні функції.

Оновлення: fswatch тепер можна використовувати на багатьох платформах, включаючи BSD, Debian та Windows.

Синтаксис / Простий приклад

Новий спосіб перегляду декількох шляхів - для версій 1.x та новіших :

fswatch -o ~/path/to/watch | xargs -n1 -I{} ~/script/to/run/when/files/change.sh

Примітка: Виведення числа by -oбуде додано до кінця xargsкоманди, якщо не для -I{}. Якщо ви вирішите скористатися цим номером, поставте місце в {}будь-якій команді.

Старіший спосіб для версій 0.x :

fswatch ~/path/to/watch ~/script/to/run/when/files/change.sh

Установка з Homebrew

За станом на 12.12.13 це було додано до домашнього пива - так! Отже, оновіть список формул ( brew update) і тоді все, що вам потрібно зробити:

brew install fswatch

Установка без домашньої мови

Введіть ці команди Terminal.app

cd /tmp
git clone https://github.com/alandipert/fswatch
cd fswatch/
make
cp fswatch /usr/local/bin/fswatch

Якщо у вас немає cкомпілятора у вашій системі, можливо, вам доведеться встановити інструменти командного рядка Xcode або Xcode - обидва безкоштовні. Однак якщо це так, вам, мабуть, варто просто перевірити домашню каву .

Додаткові параметри для fswatchверсії 1.x

Usage:
fswatch [OPTION] ... path ...

Options:
 -0, --print0          Use the ASCII NUL character (0) as line separator.
 -1, --one-event       Exit fsw after the first set of events is received.
 -e, --exclude=REGEX   Exclude paths matching REGEX.
 -E, --extended        Use exended regular expressions.
 -f, --format-time     Print the event time using the specified format.
 -h, --help            Show this message.
 -i, --insensitive     Use case insensitive regular expressions.
 -k, --kqueue          Use the kqueue monitor.
 -l, --latency=DOUBLE  Set the latency.
 -L, --follow-links    Follow symbolic links.
 -n, --numeric         Print a numeric event mask.
 -o, --one-per-batch   Print a single message with the number of change events.
                       in the current batch.
 -p, --poll            Use the poll monitor.
 -r, --recursive       Recurse subdirectories.
 -t, --timestamp       Print the event timestamp.
 -u, --utc-time        Print the event time as UTC time.
 -v, --verbose         Print verbose output.
 -x, --event-flags     Print the event flags.

See the man page for more information.

Ваші вказівки чи встановлення без домашнього перекладу, здається, вже не працюють. makeвидає помилку щодо не знайденого файлу. На щастя, fswatch зараз на MacPorts, тому sudo port install fswatchпрацює для тих, хто використовує MacPorts замість Homebrew.
coredumperror

Якщо ви використовуєте команду зі статичними аргументами (наприклад, я виконував свої одиничні тести на src та тестові зміни), це може не працювати для вас. Це питання ( stackoverflow.com/questions/25689589/… ) було другою частиною, яка мені була потрібна.
jskulski

5
Я чую вас там:fswatch ./ | xargs -I{} cp {} ~/Dropbox/backup/latest/
fionbio

fswatch краще, ніж такі інструменти, як entr або When_changed, які мають деякі помилки при роботі з .git каталогом. fswatch набагато професійніший. Просто ви просто fswatch .будете контролювати поточний каталог.
анонімний

Я хотів би запропонувати fswatch -0 -v -o /path/to/watched/files | xargs -0 -n 1 -I {} [your command]з -0для значення NULL. Цей для мене працює для меншої компіляції
boldnik

95

Для цього ви можете використовувати запуск . Launchd може бути налаштований для автоматичного запуску програми при зміні контуру файлу.

Наприклад, наступний запущений конфігураційний конвеєр запустить програму, /usr/bin/loggerколи папка робочого столу мого облікового запису користувача буде змінена:

<?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>logger</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/logger</string>
        <string>path modified</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/sakra/Desktop/</string>
    </array>
</dict>
</plist>

Щоб активувати конфігураційний список, збережіть його у папці LaunchAgents у папці «Бібліотека» як «logger.plist».

З оболонки ви можете використовувати команду launchctlдля активації logger.plist, запустивши:

$ launchctl load ~/Library/LaunchAgents/logger.plist

Зараз папка на робочому столі контролюється. Кожен раз, коли вона змінюється, ви повинні бачити вихід у system.log (використовуйте Console.app). Щоб вимкнути logger.plist, запустіть:

$ launchctl unload ~/Library/LaunchAgents/logger.plist

У файлі конфігурації вище використовується WatchPathsпараметр. Крім того, ви також можете скористатися QueueDirectoriesопцією. Додаткову інформацію див. На сторінці запуску .


1
Чи є спосіб, щоб він контролював зміну вмісту файлу, а також шлях до файлу?
Cam

2
Я не думаю, що так. Для цього можна використовувати opensnoop .
сакра

1
Я почав це працювати, але тоді, коли я переключився /usr/bin/loggerзі своїм сценарієм Bash і видалив "<string>path modified</strong>"запис, я не міг знайти жодного способу, щоб мій скрипт bash дізнався, який файл на моєму робочому столі був змінений - просто так сталася подія. Я спробував подивитися $0, $1і лише отримав назву сценарію, зазначивши, що перейшов до нього.
Воломіке

Крім того, чи йде ця річ у цикл, коли вона виявляє зміну, а не лише запускає (і зупиняє), коли виявляє зміни? Я вважаю за краще це працювати на вимогу, а не продовжувати працювати в циклі, який каже мені, що, наприклад, 2 дні тому щось змінилося на моєму робочому столі, записуючи це в журнал знову і знову. Отже, чи потрібно використовувати якийсь варіант інтервалу в цьому списку?
Воломіке

Чудова робота та пояснення
ChenSmile

37

Facebook, сторож , доступний через Homebrew, і виглядає красиво. Він також підтримує фільтрацію:

Ці два рядки встановлюють годинник у вихідному каталозі, а потім встановлюють тригер під назвою "buildme", який запускатиме інструмент під назвою "minify-css" щоразу, коли файл CSS буде змінено. Інструменту буде передано список змінених імен файлів.

$ watchman watch ~/src

$ watchman -- trigger ~/src buildme '*.css' -- minify-css

Зауважте, що шлях повинен бути абсолютним.


1
Це, безумовно, найкращий інструмент.
BentOnCoding

1
Це дуже приємна маленька програма: Документи чудові, вона не відкриває нескінченний цикл (що, як видається, робить fswatch) і запам'ятовує годинник, який ви створили після перезавантаження, і авто запускає їх знову.
Бред

21

Ви можете поглянути на (і, можливо, розширити) мій маленький інструмент kqwait. В даний час він просто сидить навколо і чекає події запису в одному файлі, але архітектура kqueue дозволяє здійснювати ієрархічну укладку подій ...


Поки працює на гірському леві. Дуже хороша!
Скотт

Тож це насправді дивовижно. Я зіткнувся з невеликою проблемою fswatch(що теж чудово, оскільки її така легка обгортка її можна було б також змінити, щоб зробити належну річ, я впевнений), де вона запускатиметься під час запуску таких речей git status(що насправді виконується кожного разу zsh на моїй машині відображається підказка ...), яка насправді накручує цей складний сценарій у мене, створюючи нескінченний цикл зворотного зв'язку. kqwait, однак, надає інформацію про змінений файл, і не спрацьовує git status. Мені це потрібно, щоб стріляти по запису, хоча.
Стівен Лу

2
$ brew install kqwait && while true; do kqwait doc/my_file.md; make; done
Джошуа Кук

15

watchdog - це кросплатформенний API пітона для перегляду файлів / каталогів, і він має вбудований інструмент "трюки", який дозволяє запускати дії (включаючи команди оболонки), коли відбуваються події (включаючи новий доданий файл, видалений файл та змінений файл).


7

Це лише згадати entr як альтернативу OSX для запуску довільних команд при зміні файлів. Я вважаю це простим і корисним.



3

Правка: fsw об’єднано в fswatch. У цій відповіді fswзараз слід читати будь-яке посилання на fswatch.

Я написав fswatchзаміну в C ++ під назвою, fswяка має кілька вдосконалень:

  • Це проект системи GNU Build System, який будується на будь-якій підтримуваній платформі (OS X v.> = 10.6) з

    ./configure && make && sudo make install
    
  • Кілька шляхів можуть бути передані як різні аргументи:

    fsw file-0 ... file-n 
    
  • У ньому зберігається детальний запис із усією інформацією про подію, наприклад:

    Sat Feb 15 00:53:45 2014 - /path/to/file:inodeMetaMod modified isFile 
    
  • Його вихід легко проаналізувати, так що fswвихід може бути перенесений на інший процес.

  • Затримка може бути налаштована за допомогою -l, --latency.
  • Прапори чисельних подій можна записати замість текстових з допомогою -n, --numeric.
  • Формат часу можна налаштувати за допомогою strftimeрядків формату з -t, --time-format.
  • Час може бути місцевим часом машини (за замовчуванням) або UTC часом -u, --utc-time.

Отримання fsw:

fswбуде розміщений на GitHub і може бути отримана клонуванням його сховище:

    git clone https://github.com/emcrisostomo/fsw

Встановлення fsw:

fsw можна встановити за допомогою наступних команд:

    ./configure && make && sudo make install

Додаткова інформація:

Я також написав вступний пост у блозі, де можна знайти пару прикладів того, як це fswпрацює.


2

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


9
Так, я знаю, я намагався це використати кілька разів, жодного разу успішно не налагоджував це, чи не могли б ви надати мені приклад?
Монетний двір

1
Це посилання, а не відповідь
Ден Розенстарк

2

Моя вилка fswatch забезпечує функціональність inotifywait -mтрохи менше (не чекайте, більше! У мене набагато більше проблем на Linux з inotifywait...) зручним для розбору результатом.

Це поліпшення оригіналу, fswatchоскільки воно надсилає фактичний шлях до зміненого файлу через STDOUT, а не вимагає від вас програми, яку він розщедрить.

Це було твердим роклом, як фундамент серії страхітливих сценаріїв, які я використовую для автоматизації роботи.

(це поза темою) inotifywaitдля Linux, з іншого боку, потрібна велика кількість хитрощів, і я все ще не знайшов хорошого способу управління цим, хоча я думаю, що на основі цього node.jsможе бути квиток.


1
Справа, вилка fswatch. Є чи, що на Homebrew?
fatuhoku

1
Відповідь - ні; але вони над цим працюють . Щоб встановити його дуже швидко просто brew install https://raw.github.com/mlevin2/homebrew/116b43eaef08d89054c2f43579113b37b4a2abd3/Library/Formula/fswatch.rb
fatuhoku

1

У мене є ГІСТ для цього, і використання досить просте

watchfiles <cmd> <paths...>

Для ілюстрації, наступна команда повторюватиметься Hello Worldкожного разу, коли змінюється file1АБО file2; і перевірка інтервалу за замовчуванням - 1 секунда

watchfiles 'echo Hello World' /path/to/file1 /path/to/file2 

Якщо я хочу перевіряти кожні 5 секунд, я можу використовувати -tпрапор

watchfiles -t 'echo Hello World' /path/to/file1 /path/to/file2 
  • -vвмикає verboseрежим, який відображає інформацію про налагодження
  • -qробить watchfilesвиконання тихо ( #буде показано, щоб користувач міг бачити, як програма виконується)
  • -qqзмушує watchfilesвиконувати повністю тихо
  • -h показує допомогу та використання

https://gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55


0

Я закінчила це робити для macOS. Я впевнений, що це багато в чому страшно:

#!/bin/sh
# watchAndRun
if [ $# -ne 2 ]; then
    echo "Use like this:"
    echo "   $0 filename-to-watch command-to-run"
    exit 1
fi
if which fswatch >/dev/null; then
    echo "Watching $1 and will run $2"
    while true; do fswatch --one-event $1 >/dev/null && $2; done
else
    echo "You might need to run: brew install fswatch"
fi

Я не міг зрозуміти синтаксис fswatch. Що дратує і робить сценарій важко зупинити.
Дан

0

Якщо ви хочете використовувати NodeJS, ви можете використовувати пакет під назвою chokidar (або власне chokidar-cli ) для перегляду, а потім використовуватиrsync (в комплекті з Mac):

Команда Rsync:

$ rsync -avz --exclude 'some-file' --exclude 'some-dir' './' '/my/destination'

Chokidar cli (встановлюється глобально через npm):

chokidar \"**/*\" -c \"your-rsync-command-above\"


-3

Ось проста альтернатива для єдиного рядка для користувачів, які не мають watchкоманди, які хочуть виконувати команду кожні 3 секунди:

while :; do your-command; sleep 3; done

Це нескінченний цикл, який в основному такий же, як робити наступне:

watch -n3 your-command


3
Це НЕ те саме, що використовувати бібліотеку, яка слухає події з файлової системи. Якщо у вашому прикладі your-commandчи дискові введення / виведення, це гарантовано читання / запис диска кожні 3 секунди - або 10 800 разів щогодини. Використовуючи події файлової системи, ви б гарантували, що введення-виведення (та інші дорогі операції) трапляються лише при зміні файлу (що, як правило, відбувається лише пару разів на годину.)
Ной Суссман,

Правда, і добре врахувати. Мені зазвичай потрібні watchречі для тимчасової кількості часу, щоб побачити, що щось робить. Я не використовую свою згадану техніку для виробничих програм або чогось подібного. Наприклад, я хотів би побачити прогрес dd, і моя техніка робить це можливим (замінюючи, your-commandякщо це доречно, щоб надіслати відповідний сигнал dd).
trusktr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.