You want to automatically run a script in OS X every time there is an update in your network connection (e.g. going on- and offline). In particular you may want to run a script to gather information about your environment, guess your current location and execute some tasks accordingly. Also, for some weird reason, you don’t want to use an application such as MarcoPolo or Proxi in order to do this.
By far the most reliable way I’ve found to do this is using crankd that, in a very similar way to launchd, allows you to run scripts in response to events such as network changes, filesystem activity, and application launching. The process to get started is not terribly complicated, but you need to be careful following instructions.
-
Download and install PyMacAdmin, this includes
crankd
. -
Once installed, open a terminal and run:
$ /usr/local/sbin/crankd.py
For some reason on my computer this crashes with an error about some undefined
NSNotificationHandler
, however you can safely disregard that error. If it didn’t crash then just type ⌃ ctrlC to exit the program. The important point is that it would have created an example configuration file in:~/Library/Preferences/com.googlecode.pymacadmin.crankd.plist
. -
Open the configuration file in a text editor and modify it so that it looks like the following:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>SystemConfiguration</key> <dict> <key>State:/Network/Global/IPv4</key> <dict> <key>command</key> <string>/absolute/path/to/your/script</string> </dict> </dict> </dict> </plist>
replacing
/absolute/path/to/your/script
with the actual path to your script. -
This will cause your script to be called every time that there is a change in your connection, in particular when going on- and offline. If you want to test and debug your script, you can go back to your terminal and run
$ /usr/local/sbin/crankd.py
On the output you will also get sensible messages about what
crankd
is doing. Try turning on/off your wireless connection, or plugging and unplugging your ethernet cable. -
If everything seems to work, now you probably would like to have your system automatically run and keep alive the
crankd
daemon. For this we use, as usual,launchd
. Create a new file such as~/Library/LaunchAgents/org.crankd.plist
with the following contents:<?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>KeepAlive</key> <true/> <key>Label</key> <string>org.crankd.plist</string> <key>ProgramArguments</key> <array> <string>/usr/local/sbin/crankd.py</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
To start the daemon right now, type the following on the terminal:
$ launchctl load ~/Library/LaunchAgents/org.crankd.plist
That’s it. Turn your connection on/off to check that your script is working properly. The daemon will also be automatically started the next time you restart your computer.
-
By the way, if you are reading this you probably also want to know how, within your script, to detect whether you have an active connection and, if you do have a connection, to somehow guess your current location. Some good ideas are to check the contents of
/etc/resolv.conf
(the file doesn’t exist if you’re offline), or to have a look at the output fromifconfig
.