MacOS – how to get shell scripts to run at startup on Yosemite

macosNetworkterminal

There is a directory in System/Library for startup items I presume: StartupItems

I need to have a shell script that will configure ethernet interface at start up, with local network address and subnet mask. I need to do this because the
network preferences for configuring the ethernet interface will NOT set it
using manual settings. THIS appears to be a serious bug, or my installation
is bad.

I was given the advice to use networksetup from the command line but that
will not configure the ethernet interface in such a way that the configurations will be there on reboot.

The script needs to do its work with root privileges, or with sudo, but I
am assuming that if it uses sudo, there will be a password dialog presented
at boot time when the boot process gets to that script.

(I have had enough experience with FreeBsd and Linux to find my way around
in the terminal, but not necessarily as it applies to Mac OSX)

Best Answer

One way of doing it would be assigning the script a launchd service:

Create the shell script as usual. Then you can make a launchd service to run it at startup. Those are located at /Library/LaunchDaemons. These are in the XML property list format. Create another and populate it with 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>Label</key>
        <string>com.example.app</string>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/sh</string>
            <string>/path/to/script</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <false/>
    </dict>
</plist>

Change com.example.app, /bin/sh and /path/to/script as required.

The script will then run while the system is booting. If it runs too early, you can either write the script to try and do what it needs to do until it succeeds, or have it exit with a non-zero error code and add this to the property list before the </dict> line:

<key>KeepAlive</key>
<dict>
     <key>SuccessfulExit</key>
     <false/>
</dict>

For more on OS X launch daemons and services, I suggest looking here for a nice quick-reference on making them, or here for a more comprehensive reference on what launchd can do.