Surveillez les modifications d'un dossier et exécutez une commande lorsqu'une modification est détectée

10

Existe-t-il un moyen simple d'exécuter automatiquement une commande (Terminal) chaque fois qu'un fichier est modifié dans un dossier spécifique?

Cela devrait être possible via la ligne de commande, ou une application intégrée au système, pas d'applications tierces.

Des idées?

Louis B.
la source

Réponses:

6

Enregistrez une liste de propriétés comme celle-ci sous ~/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>

L'agent peut être chargé avec launchctl load ~/Library/LaunchAgents/test.plistou en se déconnectant puis en se reconnectant. L'application des modifications nécessite le déchargement et le chargement de la liste.

Tilde expansion ( ~/) fonctionne par défaut dans WatchPaths. EnableGlobbing ajoute une extension générique et tilde pour ProgramArguments, mais cela n'affecte pas Program ou WatchPaths.

Si un fichier surveillé est modifié dans les dix secondes suivant la dernière invocation, un message comme celui-ci est ajouté à system.log:

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

Une façon de se débarrasser des messages est d'ajouter quelque chose comme sleep 10à la fin des scripts. Définir ThrottleInterval sur 10 n'aide pas.

Les changements dans les sous-dossiers des dossiers surveillés ne sont pas détectés.

Voir man launchdet man launchd.plistpour plus d'informations.

Lri
la source
5

entr (1) est un utilitaire pour exécuter des commandes lorsque les fichiers changent. Il lit une liste de fichiers sur STDIN et utilise kqueue (2) pour éviter l'interrogation.

Exemple:

ls my_project/*.html | entr echo "file changed"
eradman
la source
3

Vous pouvez utiliser des actions de dossier, qui vous permettent d'exécuter des scripts (Automator) chaque fois que le contenu d'un dossier change. Autant que je sache, Automator dispose d'un modèle qui vous permet de créer facilement une nouvelle action de dossier et de la joindre au dossier souhaité. Et en ajoutant une action "Run Shell Script", vous devriez juste obtenir l'effet souhaité.

xéophine
la source
5
Merci, mais il semble que les "Actions sur les dossiers" ne soient déclenchées que lorsqu'un fichier est ajouté au dossier, et non lorsqu'un fichier existant est vérifié.
Louis B.
3

Les actions sur les dossiers conviennent parfaitement au déclenchement lorsqu'un fichier est ajouté ou modifié.

Cependant, si votre définition de modifié inclut la suppression d'un fichier, les actions du dossier OSX ne détectent pas si un fichier a été supprimé.

Pour répondre à la question:

  1. Téléchargez les dépendances FileWatcher ici: https://github.com/eonist/swift-utils

  2. Familiarisez-vous avec l'exécution de swift dans la ligne de commande: http://krakendev.io/blog/scripting-in-swift

  3. Utilisez ce code pour regarder un dossier.

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
}
éoniste
la source
1

Automator dispose d'un type de flux de travail appelé "Action sur le dossier" qui s'exécute automatiquement lorsqu'un élément est ajouté à un dossier. Créez-en un, puis utilisez l'action «Exécuter le script shell».

Timothy Mueller-Harder
la source
4
Merci, mais il semble que les "Actions sur les dossiers" ne soient déclenchées que lorsqu'un fichier est ajouté au dossier, et non lorsqu'un fichier existant est vérifié.
Louis B.
Ah d'accord. Désolé.
Timothy Mueller-Harder
0

Vous voudrez peut-être essayer quelque chose comme ceci:

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
Holger von Ameln
la source
Vous devez au moins également ls -lintercepter les modifications de fichiers.
nohillside
à droite .... raté ça
Holger von Ameln