Mam takie usługi, które chciałbym uruchomić niemal natychmiast po zmodyfikowaniu plików.
<?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>
Nawet jeśli ThrottleInterval był ustawiony na 1 lub 0, są one uruchamiane co najwyżej co 10 sekund.
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
mówi tylko, że programy nie są uruchamiane domyślnie częściej niż co 10 sekund, ale nie wspomina, że ThrottleInterval nie można ustawić poniżej tego.
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.
Możesz utrzymać działanie programu lub skryptu przez 10 sekund i obserwować zmiany co sekundę:
#!/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
Lub to samo w 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
Ale czy jest jakiś sposób na ominięcie lub skrócenie terminu? Dotyczy to również akcji folderów.
Jeśli potrzebujesz uruchamiać skrypt częściej niż co 10 sekund, może to być kosztowne w kontekście „rozwidlenia” (czytaj: przydzielanie pamięci, uruchamianie nowych procesów itp.).
Dlatego w tym przypadku najlepiej jest napisać własnego „ demona ” (program, który działa w tle)
Polecam używać „bardziej wydajnego” języka jako BASH (moim ulubionym jest „perl”, ale ruby też jest OK), ponieważ dobry demon obsługuje limity czasu, alarmy i tak dalej - rzeczy, które są zbyt trudne do implementacji w czystym bashu. (Oczywiście demon może również uruchamiać skrypty bash - w razie potrzeby). Podstawy to:
W świecie perla istnieją już moduły, które dostrajają twój skrypt jako proces „demona”, na przykład Proc :: Daemon . Nie mam doświadczenia z rubinem, ale ten artykuł może ci pomóc.
Możesz uruchomić proces demona za pomocą Launchd przy starcie systemu, aplikacji automatora podczas logowania lub ręcznie z Terminalu.
źródło