Wie verhindere ich, dass ein launchd-Skript beim Aufwecken ausgeführt wird?

Ich habe ein einfaches launchd - Skript , das alle 30 Minuten einen Ton abspielt und aus der Benutzerbibliothek läuft ~/Library. Es wird nicht ausgeführt, wenn mein Computer schläft, aber er führt das letzte verpasste Ereignis aus, wenn der Computer aufwacht. Ich denke, das ist das erwartete Verhalten. Meine Frage ist, wie kann ich das verhindern. Wenn ich das halbstündige Ereignis verpasst habe, möchte ich nicht, dass es um 20 Minuten nach der vollen Stunde ausgeführt wird.

Hier ist der Kern meines Skripts. Es ruft ein Python-Skript auf. Ich habe versucht, einen Block in das Python-Skript einzufügen, um zu überprüfen, ob ich alle 30 Minuten innerhalb weniger Minuten bin, aber das scheint beim Aufwachen nicht zu funktionieren. (Fehlt irgendwie die Systemuhr?)

<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>

Hier ist ein Ausschnitt aus dem Python-Code, der die Zeit überprüft, bevor der Ton abgespielt wird.

time0 = datetime.datetime.now() if (time0.minute % 30) < 2: subprocess.run(["/Users/pheon/bin/afplay-vol.sh", "1", bell],check=True)

Antworten (2)

Das Problem liegt bei launchd und wie es mit Jobs umgeht, die während des Ruhezustands verpasst werden:

Aus der launchd.plistManpage ( 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.

Es gibt also ein paar Möglichkeiten, die Sie in Betracht ziehen sollten ...

  • zurück zu cron. Obwohl veraltet, cronwerden verpasste Jobs nicht ausgeführt

  • Überprüfen Sie die Tageszeit, bevor Sie den Sound abspielen (dies kann mit einem "Wrapper"-Skript oder innerhalb des Skripts selbst erfolgen.

  • schreiben Sie einen Log-Eintrag (irgendwo). Analysieren Sie beim Skriptstart das Protokoll. Wenn innerhalb der letzten 30 Minuten ein Ton abgespielt wurde, spielen Sie ihn nicht noch einmal ab.

Nach einigem Versuch, mit launchd zu spielen, bin ich zu cron zurückgekehrt. Es gab einige Probleme, Cron auf Mohave zum Laufen zu bringen. Ich habe Ratschläge von hier verwendet [ stackoverflow.com/questions/32781884/…

Ich hatte ein ähnliches Problem und habe es mit einer bedingten Shell-Auswertung behoben:

  <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>