Question: Is there a way to configure a LaunchAgent to start (and keep alive) a script when entering a specific location?

Example: When switching to the location "Office" i want to trigger a LaunchAgent that starts a script which opens a SSH tunnel that i need.

  • 1
    If you're willing to spend $19, you could try Locations: "Locations watches when your network changes and switches your settings." codehackers.net/locations . Among its list of actions is "Run a Terminal Command." I think that's non-geek speak for "run a shell script" – Doug Harris Apr 29 '10 at 21:39
  • naaah, i'm a poor IT student and want to hack this together by myself.. =) – lajuette Apr 30 '10 at 6:35

Mac OS X updates a file in /Library/Preferences/SystemConfiguration/ called preferences.plist. It updates a key called CurrentSet to the UUID of the current location (each location is given a UUID when it is created.) You can determine the name of that Location by looking for the UserDefinedName key in the dictionary with the same name as the UUID.

Example Script:

#! /bin/bash

# Proof of Concept Script to check if the location changed.

CURRENT_LOCATION=`/usr/libexec/PlistBuddy -c "Print :CurrentSet" /Library/Preferences/SystemConfiguration/preferences.plist | sed 's/\/Sets\///'`
CURRENT_LOCATION_NAME=`/usr/libexec/PlistBuddy -c "Print :Sets:$CURRENT_LOCATION:UserDefinedName" /Library/Preferences/SystemConfiguration/preferences.plist`

# If location is the one we want:
# Logger puts the message into syslog

if [ $CURRENT_LOCATION_NAME == "Office" ]; then
    logger "`date` => In the Office"

    #Commands to set up SSH Tunnel among others

# If the location is not the one we want: Undo whatever we have done.
    logger "`date` => Out of Office"

    #Commands here for when you leave the office location

Example LaunchAgent to run above script whenever the location is changed:

<?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">

Fill in the path to the script, give it an identifier and save it with the same name (eg. local.lajuette.location should be a file named local.lajuette.location.plist). Copy this file to ~/Library/LaunchAgents and run launchctl load ~/Library/LaunchAgents/name.of.plist.here.plist. With the sample files open up Console.app and check for the line: "DATE => In the Office" or "DATE => Out of Office" accordingly.

You may want to check out: How can I get a script to run every day on Mac OS X for more info on how to load and run your script using launchd if you're not sure.

  • sounds good, i'll try this out tomorrow! – lajuette Jul 4 '10 at 19:14
  • except for the polling (if i understood what you posted there launchd polls for changes every 30 secs?) this solution is almost perfect. But the polling is a no-go for me. I'd like a version that catches some event better. But +10 for you! – lajuette Jul 4 '10 at 20:41
  • @lajuette: As far as I know, launchd doesn't need to poll - it receives a message from the FSEvents API - the ThrottleInterval is used (and added here) as a safety measure to make sure it doesn't fire off more than once per 30 seconds (just in case something goes weird). You can change this or even remove this as necessary. – Chealion Jul 5 '10 at 6:36
  • Removing ThrottleInterval sets this value to its default: 10 If you can prove that the FSEvents API is used, you'll get +15 =) – lajuette Jul 5 '10 at 15:15
  • 1
    If you need it to be fired more than once every 10 seconds you can set ThrottleInterval to 0. As for what API is used - there is no documentation on this outside of the source at launchd.macosforge.org By default it uses kqueue, if kqueue is not supported on the drive then it will poll. (Kqueue is supported on HFS drives) – Chealion Jul 5 '10 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.