Cómo detengo que un script de lanzamiento se ejecute al despertar

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)

Respuestas (2)

El problema radica en launchd y cómo maneja los trabajos que se pierden durante la suspensión:

Desde la launchd.plistpá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, cronno 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.

Después de un poco de esfuerzo jugando con launchd, he vuelto a cron. Hubo algunos problemas para que cron funcionara en Mohave. Usé consejos de aquí [ stackoverflow.com/questions/32781884/…

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>