Tengo un script launchd simple que reproduce un sonido cada 30 minutos y se agota en la biblioteca del usuario ~/Library
. No se ejecuta si mi máquina está dormida, pero ejecuta el último evento perdido cuando la máquina se despierta. Creo que este es el comportamiento esperado. Mi pregunta es, ¿cómo evito que esto suceda? Si me perdí el evento de media hora, no quiero que se ejecute 20 minutos después de la hora.
Aquí está el núcleo de mi guión. Llama a un script de Python. Traté de poner un bloque en la secuencia de comandos de python para verificar que estoy dentro de unos minutos de cada 30 minutos, pero eso no parece funcionar al despertar. (¿Falta el reloj del sistema de alguna manera?)
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/python3</string>
<string>/Users/pheon/Documents/playsound.py</string>
</array>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Minute</key>
<integer>0</integer>
<dict>
<key>Minute</key>
<integer>30</integer>
</dict>
</array>
Aquí hay un fragmento del código python que verifica el tiempo antes de reproducir el sonido.
time0 = datetime.datetime.now() if (time0.minute % 30) < 2: subprocess.run(["/Users/pheon/bin/afplay-vol.sh", "1", bell],check=True)
El problema radica en launchd y cómo maneja los trabajos que se pierden durante la suspensión:
Desde la launchd.plist
página del manual ( man launchd.plist
)
Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up. If multiple intervals transpire before the computer is woken, those events will be coalesced into one event upon wake from sleep.
Entonces, hay algunas opciones a considerar...
volver a cron
. Aunque está en desuso, cron
no ejecutará trabajos que se hayan perdido
verifique la hora del día antes de reproducir el sonido (esto se puede hacer con un script "envoltorio" o dentro del propio script).
escribir una entrada de registro (en algún lugar). Al iniciar el script, analice el registro. Si se reprodujo un sonido en los últimos 30 minutos, no vuelva a reproducirlo.
Tuve un problema similar y lo solucioné usando una evaluación condicional de shell:
<key>ProgramArguments</key>
<array>
<string>zsh</string>
<string>-c</string>
<string>minute=$(date +"%M"); if [[ $minute = 00 || $minute = 30 ]]; then afplay -v 2 /System/Library/Sounds/Submarine.aiff; fi</string>
</array>
feón