How to run script at wake? I'm looking for a method to run a script (well, a single shell command) when my laptop wakes from sleep. 

This question has been asked before, but 8 years ago (for OS X Lion), and several of the answers require third-party products that are now no longer developed.

Another option might be for the script to run at any time, once per day, when it's up and running, but I don't want it to miss an allotted time slot just cause it's not awake. I'm not so bothered about triggering a script at sleep time.
launchd may do what you need. As long as your system isn't asleep the entire day, and it is scheduled using the StartCalendarInterval (see below), launchd will run your script once a day. Here's what I mean: 


If you schedule your script to run at (for example) 12:00 noon, AND your mac is awake at 12:00 noon, then your script will run at 12:00 noon.
If you schedule your script to run at (for example) 12:00 noon, BUT your mac is asleep at 12:00 noon, then your script will run as soon as your mac wakes up.


IMHO, launchd has an advantage because it is part of MacOS. The only 3rd party tool you might want to use with it is LaunchControl (instead of the native launchctl). LaunchControl is a GUI-based app used only to help you create/edit your .plist, and can help managing &amp; troubleshooting if that becomes necessary. The .plist file contains the instructions that will be used by launchd to start your program, and can be very simple. And of course you can avoid 3rd party software completely by simply creating the required .plist "manually" with a text editor.  

As mentioned above, the configuration key you need to use in your .plist to schedule the time to run your job/script is StartCalendarInterval. According to 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. 


Example

Here's an example of how to use launchdto create a User Agent. The scope of a User Agent is that it only runs for one user. Note that it is also possible to create Global Agent, or a Global Daemon that runs for multiple/all users, but we'll leave that for another day. : 


Create a script in your home directory (~/) to output the date and time whenever it's run: 


#!/bin/bash
CURRENTDATE=`date +"%c"`
echo Current Date and Time is: ${CURRENTDATE}


Name the script echodatetime.sh &amp; make it executable:

$ chmod 755 ~/echodatetime.sh  



Create a .plist file in ~/Library/LaunchAgents/sdm.simple.exampleofPLIST.plist: 



  EDIT: NOTE! DO NOT USE ~/ as shortcut for user's home directory! You must use a full path specification, or it won't work.


&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
    &lt;key&gt;Disabled&lt;/key&gt;
    &lt;false/&gt;
    &lt;key&gt;Label&lt;/key&gt;
    &lt;string&gt;seamus.simple.example&lt;/string&gt;
    &lt;key&gt;ProgramArguments&lt;/key&gt;
    &lt;array&gt;
        &lt;string&gt;/Users/seamus/echodatetime.sh&lt;/string&gt;
    &lt;/array&gt;
    &lt;key&gt;StandardErrorPath&lt;/key&gt;
    &lt;string&gt;/Users/seamus/echodatetime.error.txt&lt;/string&gt;
    &lt;key&gt;StandardOutPath&lt;/key&gt;
    &lt;string&gt;/Users/seamus/echodatetime.log.txt&lt;/string&gt;
    &lt;key&gt;StartCalendarInterval&lt;/key&gt;
    &lt;array&gt;
      &lt;dict&gt;
          &lt;key&gt;Hour&lt;/key&gt;
          &lt;integer&gt;1&lt;/integer&gt;
          &lt;key&gt;Minute&lt;/key&gt;
          &lt;integer&gt;25&lt;/integer&gt;
      &lt;/dict&gt;
      &lt;dict&gt;
          &lt;key&gt;Hour&lt;/key&gt;
          &lt;integer&gt;1&lt;/integer&gt;
          &lt;key&gt;Minute&lt;/key&gt;
          &lt;integer&gt;26&lt;/integer&gt;
      &lt;/dict&gt;
      &lt;dict&gt;
          &lt;key&gt;Hour&lt;/key&gt;
          &lt;integer&gt;1&lt;/integer&gt;
          &lt;key&gt;Minute&lt;/key&gt;
          &lt;integer&gt;27&lt;/integer&gt;
      &lt;/dict&gt;
      &lt;dict&gt;
          &lt;key&gt;Hour&lt;/key&gt;
          &lt;integer&gt;1&lt;/integer&gt;
          &lt;key&gt;Minute&lt;/key&gt;
          &lt;integer&gt;28&lt;/integer&gt;
      &lt;/dict&gt;
      &lt;dict&gt;
          &lt;key&gt;Hour&lt;/key&gt;
          &lt;integer&gt;1&lt;/integer&gt;
          &lt;key&gt;Minute&lt;/key&gt;
          &lt;integer&gt;29&lt;/integer&gt;
      &lt;/dict&gt;
    &lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;


This .plist will cause ~/echodatetime.sh to be executed at the following times every day:
  01:25
  01:26
  01:27
  01:28
  01:29  


  You can change the integer values in the array for the key StartCalendarInterval to get the timing that suits you. This is just an example that I used for testing. 


The example above shows a "burst" of five (5) runs at one minute intervals. This was done to show the somewhat odd syntax required for such a schedule. Scheduling a single event to run once a day, every day, at 12:00 noon may be accomplished by substituting the simpler StartCalendarInterval key shown below into the .plist shown above: 

    &lt;key&gt;StartCalendarInterval&lt;/key&gt;
    &lt;array&gt;
        &lt;dict&gt;
            &lt;key&gt;Hour&lt;/key&gt;
            &lt;integer&gt;12&lt;/integer&gt;
            &lt;key&gt;Minute&lt;/key&gt;
            &lt;integer&gt;0&lt;/integer&gt;
        &lt;/dict&gt;
    &lt;/array&gt;  



load your job &amp; check that it's running: 


$ launchctl load ~/Library/LaunchAgents/sdm.simple.exampleofPLIST.plist  
$ launchctl list | grep seamus
  -   0   seamus.simple.example 



Monitor the output file declared in the StandardOutPath key:


$ tail -f ~/echodatetime.log.txt  


After loading the .plist file, you will see the datetime output at the times designated in the StartCalendarInterval key: at one minute intervals beginning at 01:25 and ending at 01:29 if you use my .plist file. 

Miscellany


The .plist files above have been tested, and operated successfully on my macbook pro running Mojave (ver 10.14.6). Also verified the behavior of launchd when an event schedule occurs during sleep: The task ran immediately after the mac "woke up", and logged the time it awakened (i.e. not the scheduled time).
Yes, the .plist syntax is arcane! Consider using LaunchControl instead of manually hacking these files.
A potentially useful hint: You can check the syntax of your .plist file like so: 


$ plutil -lint /Users/seamus/Library/LaunchAgents/sdm.simple.exampleofPLIST.plist  
/Users/seamus/Library/LaunchAgents/sdm.simple.exampleofPLIST.plist: OK  



When you're finished with this example, you may remove the job from launchd, and then delete or move the file from your folder ~/Library/LaunchAgents. Otherwise, your job will be re-started by launchd next time you log in: 


$ launchctl remove seamus.simple.example  
$ mv ~/LaunchAgents/sdm.simple.exampleofPLIST.plist ~/archive


Alternatively, leave the file where it is, and set the Disabled key  to true in the .plist:

    &lt;key&gt;Disabled&lt;/key&gt;
    &lt;true/&gt;