Czy na komputerze Mac istnieje polecenie takie jak „obejrzyj” lub „inotifywait”?

287

Chcę obejrzeć folder na moim komputerze Mac (Snow Leopard), a następnie wykonać skrypt (podając nazwę pliku, który został właśnie przeniesiony do folderu (jako parametr ... x.sh „nazwa pliku”)).

Mam skrypt napisany w bash (x.sh), który przeniesie niektóre pliki i inne rzeczy na wejściu 1 $ Potrzebuję tylko OSX, aby podać nazwę pliku, gdy nowe pliki / foldery zostaną przeniesione / utworzone do katalogu.

Jakieś takie polecenie?

Mennica
źródło
1
Powinieneś zapytać, jak robi to DropBox, ponieważ prawdopodobnie wypróbowali wszystkie dostępne opcje.
Jeff Burdges
2
@JeffBurdges Nie jestem pewien, czy byłoby to łatwe przedsięwzięcie. Powiedziałbym jednak, że po przejrzeniu FSEvents Reference firmy Apple byłoby naprawdę głupie, gdyby Dropbox tego nie używał. Wykorzystanie fswatchprzedstawione jako odpowiedź w rzeczywistości korzysta z tej metody.
Steven Lu

Odpowiedzi:

447

fswatch

fswatch to mały program wykorzystujący interfejs API Mac OS X FSEvents do monitorowania katalogu. Po odebraniu zdarzenia dotyczącego jakiejkolwiek zmiany w tym katalogu, określone polecenie powłoki jest wykonywane przez/bin/bash

Jeśli korzystasz z systemu GNU / Linux, inotifywatch (część inotify-toolspakietu w większości dystrybucji) zapewnia podobną funkcjonalność.

Aktualizacja: fswatch można teraz używać na wielu platformach, w tym BSD, Debian i Windows.

Składnia / prosty przykład

Nowy sposób, w jaki można oglądać wiele ścieżek - dla wersji 1.xi nowszych :

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

Uwaga: Liczba wyjściowa przez -ozostanie dodana na końcu xargspolecenia, jeśli nie dla -I{}. Jeśli zdecydujesz się użyć tego numeru, umieść {}dowolne miejsce w swoim poleceniu.

Starszy sposób na wersje 0.x :

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

Instalacja z Homebrew

Od 9.12.2013 został ponownie dodany do homebrew - tak! Zaktualizuj więc listę formuł ( brew update), a wszystko, co musisz zrobić, to:

brew install fswatch

Instalacja bez Homebrew

Wpisz te polecenia w Terminal.app

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

Jeśli nie masz ckompilatora w systemie, może być konieczne zainstalowanie narzędzi wiersza polecenia Xcode lub Xcode - oba są bezpłatne. Jeśli tak jest, prawdopodobnie powinieneś po prostu sprawdzić homebrew .

Dodatkowe opcje dla fswatchwersji 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.
cwd
źródło
Wydaje się, że instrukcje lub instalacja bez homebrew już nie działają. makezgłasza błąd dotyczący nie znalezienia pliku makefile. Na szczęście fswatch jest teraz na MacPorts, więc sudo port install fswatchdziała, dla tych z nas, którzy używają MacPorts zamiast Homebrew.
coredumperror
Jeśli używasz polecenia z argumentami statycznymi (na przykład uruchamiałem moje testy jednostkowe na src i zmiany testowe), może to nie działać. To pytanie ( stackoverflow.com/questions/25689589/... ) było drugim, którego potrzebowałem.
jskulski
5
Słyszę cię tam:fswatch ./ | xargs -I{} cp {} ~/Dropbox/backup/latest/
fionbio
fswatch jest lepszy niż narzędzia takie jak entr lub when_changed, które mają pewne błędy podczas obsługi katalogu .git. fswatch jest znacznie bardziej profesjonalny. Po prostu fswatch .będziesz monitorować bieżący katalog.
anonimowy
Proponuję fswatch -0 -v -o /path/to/watched/files | xargs -0 -n 1 -I {} [your command]ze -0dla wartości null. Ten działa dla mnie na mniejszą kompilację
boldnik
95

Możesz użyć do tego celu uruchomionego . Uruchomione można skonfigurować tak, aby automatycznie uruchamiało program po zmodyfikowaniu ścieżki pliku.

Na przykład następujący plist uruchomionej konfiguracji uruchomi program, /usr/bin/loggergdy folder pulpitu mojego konta użytkownika zostanie zmodyfikowany:

<?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>

Aby aktywować plist konfiguracji, zapisz go w folderze LaunchAgents w folderze Library jako „logger.plist”.

Z poziomu powłoki możesz następnie użyć polecenia, launchctlaby aktywować logger.plist, uruchamiając:

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

Folder na pulpicie jest teraz monitorowany. Za każdym razem, gdy jest zmieniany, powinieneś zobaczyć wynik w pliku system.log (użyj Console.app). Aby dezaktywować logger.plist, uruchom:

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

W powyższym pliku konfiguracyjnym jest używana WatchPathsopcja. Możesz też użyć tej QueueDirectoriesopcji. Aby uzyskać więcej informacji, zobacz stronę podręcznika uruchomionego .

sakra
źródło
1
czy istnieje sposób, aby monitorował zmianę zawartości pliku oraz ścieżki pliku?
Cam
2
Nie wydaje mi się W tym celu możesz użyć opensnoop .
sakra
1
Udało mi się to uruchomić, ale kiedy przełączyłem się /usr/bin/loggerze skryptem Bash i usunąłem "<string>path modified</strong>"wpis, nie mogłem znaleźć sposobu, aby mój skrypt bash wiedział, który plik na pulpicie został zmodyfikowany - po prostu zdarzenie miało miejsce. Próbowałem patrząc $0, $1i tylko dostał nazwę skryptu sam, zauważając, przeszedł do niego.
Volomike
Czy ta rzecz przechodzi w pętlę po wykryciu zmiany, a nie tylko uruchamia się (i zatrzymuje) po wykryciu zmiany? Wolałbym, żeby działał na żądanie, nie działał w pętli, mówiąc mi, na przykład, że 2 dni temu coś zmieniło się na moim pulpicie, ciągle zapisując to w logu. Czy więc musimy użyć jakiejś opcji interwału na tym liście?
Volomike
Wielka Praca i Wyjaśnienie
ChenSmile
37

Strażnik Facebooka , dostępny za pośrednictwem Homebrew, również wygląda ładnie. Obsługuje również filtrowanie:

Te dwa wiersze ustanawiają obserwację w katalogu źródłowym, a następnie konfigurują wyzwalacz o nazwie „buildme”, który będzie uruchamiał narzędzie o nazwie „minify-css” przy każdej zmianie pliku CSS. Do narzędzia zostanie przekazana lista zmienionych nazw plików.

$ watchman watch ~/src

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

Zauważ, że ścieżka musi być bezwzględna.

Jakub Holý
źródło
1
To zdecydowanie najlepsze narzędzie.
BentOnCoding
1
Jest to bardzo ładny mały program: Dokumenty są świetne, nie otwiera nieskończonej pętli (co wydaje się robić fswatch) i pamięta zegarki utworzone po ponownym uruchomieniu i auto uruchamia je ponownie.
Brad
21

Możesz rzucić okiem (a może rozwinąć) moje małe narzędzie kqwait. Obecnie po prostu siedzi i czeka na zdarzenie zapisu w jednym pliku, ale architektura kqueue pozwala na hierarchiczne układanie zdarzeń ...

sschober
źródło
Działa do tej pory na lwa górskiego. Bardzo dobrze!
Scott
To jest naprawdę niesamowite. Wpadłem na mały problem z fswatch(co też jest w porządku, ponieważ jest to tak lekkie opakowanie, że można go również zmodyfikować, aby zrobić właściwą rzecz, jestem pewien), gdzie będzie się uruchamiał podczas uruchamiania takich rzeczy git status(które są faktycznie uruchamiane za każdym razem zsh monit jest renderowany na mojej maszynie ...) co właściwie trochę psuje ten skomplikowany skrypt, który mam, tworząc nieskończoną pętlę sprzężenia zwrotnego. kqwait dostarcza jednak informacji o zmienionym pliku i nie jest wyzwalany przez git status. Potrzebuję go jednak do odpalenia podczas pisania.
Steven Lu
2
$ brew install kqwait && while true; do kqwait doc/my_file.md; make; done
Joshua Cook
15

watchdog to wieloplatformowy API Pythona do oglądania plików / katalogów i ma wbudowane narzędzie „sztuczek”, które pozwala na uruchamianie akcji (w tym poleceń powłoki), gdy wystąpią zdarzenia (w tym nowy dodany plik, usunięty plik i zmieniony plik).

gfxmonk
źródło
7

Jest to tylko wzmianka o entr jako alternatywie w OSX do uruchamiania dowolnych poleceń w przypadku zmiany plików. Uważam to za proste i przydatne.

Donny Winston
źródło
5

Oto jeden-liner używając sschober„s narzędzie .

$ while true; do kqwait ./file-to-watch.js; script-to-execute.sh; done
Joshua Cook
źródło
$ brew install kqwait
Joshua Cook
3

Edycja: fsw zostało połączone fswatch. W tej odpowiedzi fswnależy teraz przeczytać wszelkie odniesienia do fswatch.

Napisałem fswatchzamiennik w C ++ o nazwie, fswktóry zawiera kilka ulepszeń:

  • Jest to projekt GNU Build System, który opiera się na dowolnej obsługiwanej platformie (OS X v.> = 10.6) z

    ./configure && make && sudo make install
    
  • Wiele ścieżek można przekazać jako różne argumenty:

    fsw file-0 ... file-n 
    
  • Zrzuca szczegółowy zapis ze wszystkimi informacjami o zdarzeniu, takimi jak:

    Sat Feb 15 00:53:45 2014 - /path/to/file:inodeMetaMod modified isFile 
    
  • Jego dane wyjściowe można łatwo przeanalizować, dzięki czemu fswdane wyjściowe można skierować do innego procesu.

  • Opóźnienie można dostosować za pomocą -l, --latency.
  • Flagi zdarzeń numerycznych można zapisać zamiast flag tekstowych za pomocą -n, --numeric .
  • Format czasu można dostosować za pomocą strftimeciągów formatu za pomocą -t, --time-format.
  • Czas może być czasem lokalnym maszyny (domyślnie) lub czasem UTC za pomocą -u, --utc-time.

Pierwsze fsw:

fswjest hostowany na GitHub i można go uzyskać klonując jego repozytorium:

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

Instalowanie fsw:

fsw można zainstalować za pomocą następujących poleceń:

    ./configure && make && sudo make install

Dalsza informacja:

Napisałem również wstępny post na blogu, w którym można znaleźć kilka przykładów na temat tego, jak fswdziała.

Enrico M. Crisostomo
źródło
2

Akcje folderów Apple OSX pozwalają zautomatyzować zadania na podstawie akcji podjętych w folderze.

Asaf
źródło
9
Tak, wiem, próbowałem użyć tego kilka razy, nigdy nie udało mi się go uruchomić, czy możesz dać mi przykład?
Mięta
1
To jest link, a nie odpowiedź
Dan Rosenstark
2

Mój widelec fswatch zapewnia funkcjonalność inotifywait -mz nieco mniejszym (nie czekaj, więcej! Mam dużo więcej problemów w Linuksie z inotifywait...) wyjściem przyjaznym dla parsowania.

Jest to ulepszenie w stosunku do oryginału fswatch ponieważ wysyła rzeczywistą ścieżkę zmienionego pliku za pośrednictwem STDOUT, zamiast wymagać dostarczenia programu, który rozwiąże.

Jest solidny jak fundament serii przerażających skryptów bashowych, których używam do automatyzacji rzeczy.

(jest to nie na temat) inotifywaitw Linuksie, z drugiej strony, wymaga dużo kłopotów na nim, a ja wciąż nie wymyśliłem dobrego sposobu zarządzania, chociaż myślę, że coś opartego node.jsmoże być biletem.

Steven Lu
źródło
1
Racja, widelec fswatch. Czy to na Homebrew?
fatuhoku
1
Odpowiedź brzmi nie; ale pracują nad tym . Aby zainstalować to naprawdę szybko, po prostu brew install https://raw.github.com/mlevin2/homebrew/116b43eaef08d89054c2f43579113b37b4a2abd3/Library/Formula/fswatch.rb
fatuhoku,
1

Mam do tego GIST, a użycie jest dość proste

watchfiles <cmd> <paths...>

Aby to zilustrować, następujące polecenie będzie powtarzane przy Hello Worldkażdej zmianie file1LUB file2; a domyślna kontrola interwału to 1 sekunda

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

Jeśli chcę sprawdzać co 5 sekund, mogę użyć -tflagi

watchfiles -t 'echo Hello World' /path/to/file1 /path/to/file2 
  • -vwłącza verbosetryb, który wyświetla informacje debugowania
  • -qpowoduje watchfileswykonanie po cichu ( #zostanie pokazane, aby użytkownik mógł zobaczyć, że program się wykonuje)
  • -qqsprawia, że watchfileswykonanie jest całkowicie ciche
  • -h pokazuje pomoc i użycie

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

Thiagoh
źródło
0

Skończyło się to na macOS. Jestem pewien, że jest to okropne na wiele sposobów:

#!/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
Dan Rosenstark
źródło
Nie mogłem zrozumieć składni fswatch bez czasu. Co jest denerwujące i sprawia, że ​​skrypt jest trudny do zatrzymania.
Dan Rosenstark
0

Jeśli chcesz korzystać z NodeJS, możesz użyć pakietu o nazwie chokidar (lub chokidar-cli faktycznie ) do oglądania, a następnie użyć rsync(dołączonego do Maca):

Komenda Rsync:

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

Chokidar cli (instalowany globalnie przez npm):

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

prograhammer
źródło
-3

Oto prosta alternatywa dla pojedynczej linii dla użytkowników, którzy nie mają watchpolecenia, którzy chcą wykonać polecenie co 3 sekundy:

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

Jest to nieskończona pętla, która jest zasadniczo taka sama, jak wykonywanie następujących czynności:

watch -n3 your-command

trusktr
źródło
3
NIE jest to to samo, co użycie biblioteki, która nasłuchuje zdarzeń z systemu plików. Jeśli w twoim przykładzie your-commandjest dysk I / O, to jest to gwarantowany dysk do odczytu / zapisu co 3 sekundy - lub 10 800 razy co godzinę. Używając zdarzeń systemu plików masz gwarancję, że operacje we / wy (i inne kosztowne operacje) będą miały miejsce tylko wtedy, gdy zmienisz plik (co zwykle trwa tylko kilka razy na godzinę).
Noah Sussman
Prawda i warto to rozważyć. Zwykle potrzebuję różnych watchrzeczy, aby zobaczyć, co się dzieje. Nie używam wspomnianej techniki w aplikacjach produkcyjnych ani nic podobnego. Na przykład chciałbym zobaczyć postęp dd, a moja technika sprawia, że ​​tak się dzieje (zastępując your-commandodpowiednio, aby wysłać odpowiedni sygnał dd).
trusktr