Überwachen Sie einen Ordner auf Änderungen und führen Sie einen Befehl aus, wenn eine Änderung erkannt wird


10

Gibt es eine einfache Möglichkeit, einen (Terminal-) Befehl jedes Mal automatisch auszuführen, wenn eine Datei in einem bestimmten Ordner geändert wird?

Dies sollte über die Befehlszeile oder eine in das System integrierte Anwendung möglich sein, keine Anwendungen von Drittanbietern.

Irgendwelche Ideen?



Antworten:


6

Speichern Sie eine Eigenschaftsliste wie folgt ~/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>

Der Agent kann mit launchctl load ~/Library/LaunchAgents/test.plistoder durch Abmelden und erneutes Anmelden geladen werden . Um Änderungen zu übernehmen, muss die Plist entladen und geladen werden .

Tilde ~/extension ( ) funktioniert standardmäßig in WatchPaths. EnableGlobbing fügt Platzhalter- und Tilde-Erweiterungen für ProgramArguments hinzu, hat jedoch keine Auswirkungen auf Program oder WatchPaths.

Wenn eine überwachte Datei innerhalb von zehn Sekunden nach dem letzten Aufruf geändert wird, wird eine folgende Meldung zu system.log hinzugefügt:

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

Eine Möglichkeit, die Nachrichten zu entfernen, besteht darin sleep 10, am Ende von Skripten etwas hinzuzufügen . Das Setzen von ThrottleInterval auf 10 hilft nicht.

Änderungen in Unterordnern von überwachten Ordnern werden nicht erkannt.

Siehe man launchdund man launchd.plistfür weitere Informationen.


5

entr (1) ist ein Dienstprogramm zum Ausführen von Befehlen, wenn sich Dateien ändern. Es liest eine Liste von Dateien auf STDIN und verwendet kqueue (2) , um Abfragen zu vermeiden.

Beispiel:

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

3

Sie können Ordneraktionen verwenden, mit denen Sie (Automator-) Skripts ausführen können, wenn sich der Inhalt eines Ordners ändert. Soweit ich weiß, verfügt Automator über eine Vorlage, mit der Sie auf einfache Weise eine neue Ordneraktion erstellen und an den gewünschten Ordner anhängen können. Wenn Sie eine Aktion "Shell-Skript ausführen" hinzufügen, sollten Sie nur den gewünschten Effekt erzielen.


5
Vielen Dank, aber es scheint, dass "Ordneraktionen" nur ausgelöst werden, wenn eine Datei zum Ordner hinzugefügt wird, nicht wenn eine vorhandene Datei überprüft wird.
Louis B.

3

Ordneraktionen können problemlos ausgelöst werden, wenn eine Datei hinzugefügt oder geändert wird.

Wenn Ihre Definition von geändert jedoch das Löschen einer Datei umfasst, erkennen OSX-Ordneraktionen nicht, ob eine Datei entfernt wurde.

Um die Frage zu beantworten:

  1. Laden Sie die FileWatcher-Abhängigkeiten von hier herunter: https://github.com/eonist/swift-utils

  2. Machen Sie sich mit dem schnellen Laufen in der Befehlszeile vertraut: http://krakendev.io/blog/scripting-in-swift

  3. Verwenden Sie diesen Code, um einen Ordner anzusehen.

Code:

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

Automator verfügt über einen Workflow, der als "Ordneraktion" bezeichnet wird und automatisch ausgeführt wird, wenn einem Ordner etwas hinzugefügt wird. Erstellen Sie eine und verwenden Sie die Aktion "Shell-Skript ausführen".


4
Vielen Dank, aber es scheint, dass "Ordneraktionen" nur ausgelöst werden, wenn eine Datei zum Ordner hinzugefügt wird, nicht wenn eine vorhandene Datei überprüft wird.
Louis B.

Oh ok. Es tut uns leid.
Timothy Mueller-Harder

0

Vielleicht möchten Sie so etwas ausprobieren:

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

Sie müssen mindestens auch ls -lDateiänderungen abfangen.
Nohillside

richtig .... habe das verpasst
Holger von Ameln
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.