J'ai certains services comme celui-ci que j'aimerais exécuter presque immédiatement après la modification des fichiers.
<?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>a</string>
</array>
<key>WatchPaths</key>
<array>
<string>/Users/username/Desktop/</string>
</array>
</dict>
</plist>
Même si ThrottleInterval a été défini sur 1 ou 0, ils ne s'exécutent qu'au maximum toutes les 10 secondes.
9/9/12 4:57:05.457 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 7 seconds
9/9/12 4:57:09.541 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 3 seconds
man launchd.plist
indique seulement que les programmes ne sont pas exécutés plus de toutes les 10 secondes par défaut, mais ne mentionne pas que ThrottleInterval ne peut pas être défini en dessous.
ThrottleInterval <integer>
This key lets one override the default throttling policy imposed on jobs by launchd.
The value is in seconds, and by default, jobs will not be spawned more than once
every 10 seconds. The principle behind this is that jobs should linger around just
in case they are needed again in the near future. This not only reduces the latency
of responses, but it encourages developers to amortize the cost of program invoca-
tion.
Vous pouvez garder le programme ou le script en cours d'exécution pendant 10 secondes et surveiller les modifications chaque seconde:
#!/bin/bash
start=$(date +%s)
prev=
until (( $(date +%s) >= $start + 10 )); do
new=$(stat -f %m ~/Desktop/)
[[ $prev != $new ]] && say a
prev=$new
sleep 1
done
Ou la même chose en Ruby:
#!/usr/bin/env ruby
start = Time.now
prev = nil
until Time.now >= start + 10
current = File.mtime("#{ENV['HOME']}/Desktop/")
`say a` if current != prev
prev = current
sleep 1
end
Mais existe-t-il un moyen de contourner ou de réduire le délai? Cela s'applique également aux actions de dossier.
Si vous avez besoin de démarrer un script plus souvent que toutes les 10 secondes, il peut être coûteux en termes de "forking" (lire: allouer de la mémoire, démarrer de nouveaux processus, etc.).
Par conséquent, dans ce cas, il est préférable d'écrire votre propre " démon " (programme, ce qui s'exécute en arrière-plan)
Je vous recommande d'utiliser un langage "plus performant" comme BASH (mon préféré est "perl", mais ruby est OK aussi) car un bon démon gère les délais d'attente, les alarmes et ainsi de suite - des choses qui sont trop difficiles à implémenter en pure bash. (Bien sûr, le démon peut également exécuter vos scripts bash - si nécessaire). Les bases sont:
Dans le monde Perl, il existe déjà des modules qui ajustent votre script en tant que processus "démon", par exemple Proc :: Daemon . Je n'ai pas d'expérience avec le rubis, mais cet article peut vous aider.
Vous pouvez démarrer votre processus démon via Launchd au démarrage du système, ou depuis l'application automate lorsque vous vous connectez, ou depuis le terminal manuellement.
la source