8

Honestly, I'm finding Apple's launchctl and plist (XML?) usage to be somewhat confusing and overkill. Using Terminal, I just wanna say hey, macOS, start program.app at boot! or hey, macOS, start my /path/to/shell.sh at boot!

How can I add a boot item --remotely via Terminal/SSH/Netcat/command line/shell?

sh-3.2# system_profiler SPSoftwareDataType 
Software:

    System Software Overview:

      System Version: macOS 10.13.4 (17E199)
      Kernel Version: Darwin 17.5.0
      Boot Volume: lily
      Boot Mode: Normal
      Computer Name: lily’s MacBook Air
      User Name: System Administrator (root)
      Secure Virtual Memory: Enabled
      System Integrity Protection: Enabled
      Time since boot: 2:03
lily
  • 839
  • There's more to it than just a startup program. Do you want it to launch for only one user, all users or regardless if a user logs in? See this primer on launchd. Here's another answer on how to run something at boot (no interval) – Allan May 18 '18 at 11:32
  • My frustration is exactly the same! Why does apple make it so hard to do such simple things? I hope someone could explain to me why this is necessary.. – Student May 04 '19 at 14:50

1 Answers1

6

LaunchDaemons – Run at Boot

LaunchAgents – Run at Login

So... you need a daemon

suggest you to cat /System/Library/LaunchDaemons/com.apple.pfctl.plist or any other in the same dir and use it as reference.

Just remove unnecessary. It will be something like this:

<?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>Disabled</key>
    <false/>
    <key>Label</key>
    <string>shell.sh</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/shell.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

save the file in the same dir, but named shell.sh.plist and run

sudo launchctl load /System/Library/LaunchDaemons/shell.sh.plist

to remove script from the load list:

sudo launchctl unload /System/Library/LaunchDaemons/shell.sh.plist

this is not linux so things are done Mac way.

man launchd & man launchd.plist will provide all needed info

OR

you can use an approach described here

Creating .plist just once and pointing it to your startup script which in turn will start anything you add there without need to write new .plist every time you want to start something new.

  • thanks. im making progress with this. the script requires internet access, how do i tell the plist to execute only after network connectivity has been established? – lily May 18 '18 at 15:12
  • This answer is incomplete and will result in failure(s) when the user attempts this. – Allan May 18 '18 at 15:12
  • @Allan how do you mean? – lily May 18 '18 at 15:12
  • @lily - I posted two links in the comments. The first one is a primer on launchd and creating the plists. See that. – Allan May 18 '18 at 15:13
  • @Allan is it possible to add a one-liner script into the plist so avoid sourcing a local file? – lily May 18 '18 at 15:13
  • @lily Yes. You don't need to put a script. You can issue the command directly with command line arguments. If you want to see a good example of how to do this at boot time, click the second link in my comments – Allan May 18 '18 at 15:14
  • @Allan hmm, cant figure out which <key> to use. im going to ask a new question, keep an eye out for it, please! – lily May 18 '18 at 15:19
  • @Allan, try actually cat /System/Library/LaunchDaemons/com.apple.pfctl.plist – Igor Voltaic May 18 '18 at 15:24
  • https://apple.stackexchange.com/questions/325727/how-to-run-a-one-liner-shell-command-using-launchd – lily May 18 '18 at 15:25
  • @lily, can't comment someone else's post yet but should your script monitor online/offline state or it just waits for some time after boot until connection is established? if it's the latter than you can do it quick and dirty by using sleep <time in seconds> inside your script or simply sleep 30 && script.sh as an outside option – Igor Voltaic May 18 '18 at 15:31
  • Thanks a lot for the answer. It took me awhile to make it work: 1. I disabled SIP for me to edit/save in /System/Library/LaunchDaemons/. More information can be found in this post (https://superuser.com/questions/1159290/cant-edit-read-only-file-even-when-root/1159330) . 2. I forgot to chmod for the system to run my shell script before hand. The system did not send warnings when that is the case! – Student May 04 '19 at 16:13