How to make script run on system start/user login via terminal [duplicate]

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)


Solution 1:

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.

Solution 2:

Some time ago I used cron to do just that. You can make an entry like this

@reboot /path/to/my/script

More info here

Instead of the first five fields, one of eight special strings may appear:

       string          meaning
       ------          -------@reboot ------@reboot
       @reboot         Run once, at startup.
       @yearly         Run once a year, "0 0 1 1 *".
       @annually       (same as @yearly)
       @monthly        Run once a month, "0 0 1 * *".
       @weekly         Run once a week, "0 0 * * 0".
       @daily          Run once a day, "0 0 * * *".
       @midnight       (same as @daily)
       @hourly         Run once an hour, "0 * * * *".