У меня есть некоторые подобные сервисы, которые я хотел бы запустить почти сразу после изменения файлов.
<?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>
Даже если для ThrottleInterval задано значение 1 или 0, они запускаются не чаще, чем каждые 10 секунд.
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
только говорит, что программы запускаются не чаще, чем каждые 10 секунд по умолчанию, но не упоминает, что ThrottleInterval не может быть установлен ниже этого.
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.
Вы можете оставить программу или скрипт на 10 секунд и следить за изменениями каждую секунду:
#!/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
Или то же самое в 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
Но есть ли способ обойти или уменьшить ограничение по времени? Это также относится к действиям папки.
Если вам нужно запускать скрипт чаще, чем каждые 10 секунд, он может быть дорогостоящим с точки зрения «разветвления» (читай: выделение памяти, запуск новых процессов и т. Д.).
Поэтому в этом случае лучше всего написать собственный « демон » (программа, которая работает в фоновом режиме)
Я рекомендую вам использовать «более способный» язык в качестве BASH (мой любимый - «perl», но ruby тоже в порядке), потому что хороший демон обрабатывает тайм-ауты, аварийные сигналы и т. Д. - вещи, которые слишком сложно реализовать в чистом bash. (Конечно, демон может запускать ваши bash-скрипты - при необходимости). Основы:
В мире perl уже существуют модули, которые настраивают ваш скрипт как процесс «демон», например, Proc :: Daemon . У меня нет опыта работы с ruby, но эта статья может вам помочь.
Вы можете запустить процесс демона через Launchd при запуске системы, либо из приложения automator при входе в систему, либо из терминала вручную.
источник