Eu tenho alguns serviços como este que gostaria de executar quase imediatamente após a modificação dos arquivos.
<?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>
Mesmo que ThrottleInterval tenha sido definido como 1 ou 0, eles são executados apenas no máximo a cada 10 segundos.
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
diz apenas que os programas não são executados mais do que a cada 10 segundos por padrão, mas não menciona que ThrottleInterval não pôde ser definido abaixo disso.
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.
Você pode manter o programa ou script em execução por 10 segundos e observar as mudanças a cada segundo:
#!/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 o mesmo em 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
Mas existe alguma maneira de ignorar ou diminuir o limite de tempo? Também se aplica às ações da pasta.
Se você precisar iniciar um script com mais frequência a cada 10 segundos, pode ser caro em termos de "bifurcação" (leia-se: alocar memória, iniciar novos processos etc.).
Portanto, neste caso, é melhor escrever seu próprio " daemon " (programa, o que é executado em segundo plano)
Eu recomendo que você use uma linguagem "mais capaz" como BASH (o meu favorito é "perl", mas o ruby também é bom) porque um bom daemon lida com tempos limites, alarmes e assim por diante - coisas que são muito difíceis de implementar no bash puro. (Obviamente, o daemon também pode executar seus scripts bash - se necessário). O básico é:
No mundo perl já existem módulos que ajustam seu script como processo "daemon", por exemplo Proc :: Daemon . Não tenho experiência com ruby, mas este artigo pode ajudá-lo.
Você pode iniciar seu processo de daemon via Launchd na inicialização do sistema ou no aplicativo de automação ao fazer login ou no Terminal manualmente.
fonte