Turn off mac at a specific time to force bedtimes [duplicate]

I recently turned on a script on my PC to turn off my windows machine at a specific time. It runs as Admin, and I went as far as to make warning pop ups half an hour before hand. It was was easy as you can make scheduled tasks on windows...

However, I write this at 1:30 am. I am sitting watching youtube videos of things I don't care about on my macbook pro. I will be exhausted tomorrow.

How can I do the same for my mac?

I want to turn off the computer, as an admin so it cannot be stopped or delayed. I want to be able to set it to go off every few minutes, even if that means creating multiple routines. I'm thinking it should be a bash script.. but I am surely not the first sleepy programmer that has this need.


Solution 1:

macOS provides scheduled shutdown through Energy Saver.

Use the Schedule feature of Energy Saver preferences to set a time for your Mac to automatically start up, wake, sleep, restart, or shut down.

Unfortunately this only allows for one shut down time rather than multiple.

  1. From the Apple () menu, choose System Preferences, then click Energy Saver.
  2. Click the Schedule button, then use the checkboxes and pop-up menus to choose when to start up, wake, sleep, restart, or shut down.

https://support.apple.com/HT201988

Solution 2:

You can create scheduled tasks on macOS using launchd. You can shut down Mac from the command line using sudo shutdown -h now. Combining this, you can create the following plist file: /Library/LaunchDaemons/private.shutdown1.plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.example.volume</string>
        <key>ProgramArguments</key>
        <array>
                <string>shutdown</string>
                <string>-h</string>
                <string>now</string>
        </array>
        <key>StartCalendarInterval</key>
        <dict>
                <key>Hour</key>
                <integer>23</integer>
                <key>Minute</key>
                <integer>45</integer>
        </dict>
</dict>
</plist>

Load the plist with launchctl load. StartCalendarInterval will cause this to run at 23:45 every day. You can create multiple of these tasks (private.shutdown1 is an arbitrary name).