georges' blog

June 6, 2011

How To Automatically Turn Off Airport When Ethernet is Plugged In

Filed under: Technology — kendall @ 7:24 pm

When I’m at work, I plug in my Ethernet cable and turn off my AirPort wireless network adapter.  This is partly because the wifi in my office is a bit unreliable but also because the wired network is a lot faster.  It’s not a major hassle to do this manually–it’s only two clicks to turn it off or on. Sure, over time that has added up to over a thousand clicks, still no biggie.  But also, sometimes I forget to turn my wireless back on and those few seconds it takes to realize that my wireless is off and turn it on is a mild irritation. It also seems to cause Google Chrome to crash, often. So, cumulatively it adds up to a minor headache. So, I thought I’d automate this.  I am indebted to this post: Auto-disable AirPort when ethernet is active. Most of what you need to make this work you can find in this post, though you might need to drill down into some of the comments. Here I’ve tried to document what I did to get it to work.

First you will need to copy this script into a text document and save it as /Library/Scripts/toggleAirport.sh.

#!/bin/bash

function set_airport {

    new_status=$1

    if [ $new_status = "On" ]; then
	/usr/sbin/networksetup -setairportpower en0 on
	touch /var/tmp/prev_air_on
    else
	/usr/sbin/networksetup -setairportpower en0 off
	if [ -f "/var/tmp/prev_air_on" ]; then
	    rm /var/tmp/prev_air_on
	fi
    fi

}

function growl {

    # Checks whether Growl is installed
    if [ -f "/usr/local/bin/growlnotify" ]; then
	/usr/local/bin/growlnotify -m "$1" -a "AirPort Utility.app"
    fi

}

# Set default values
prev_eth_status="Off"
prev_air_status="Off"

eth_status="Off"

# Determine previous ethernet status
# If file prev_eth_on exists, ethernet was active last time we checked
if [ -f "/var/tmp/prev_eth_on" ]; then
    prev_eth_status="On"
fi

# Determine same for AirPort status
# File is prev_air_on
if [ -f "/var/tmp/prev_air_on" ]; then
    prev_air_status="On"
fi

# Check actual current ethernet status
if [ "`ifconfig en1 | grep \"status: active\"`" != "" ]; then
    eth_status="On"
fi

# Check actual current ethernet status for Display Ethernet
if [ "`ifconfig en3 | grep \"status: active\"`" != "" ]; then
    eth_status="On"
fi

# Check actual current ethernet status for Thunderbolt Ethernet adapter
if [ "`ifconfig en6 | grep \"status: active\"`" != "" ]; then
    eth_status="On"
fi

# And actual current AirPort status
air_status=`/usr/sbin/networksetup -getairportpower en0 | awk '{ print $4 }'`

# If any change has occured. Run external script (if it exists)
if [ "$prev_air_status" != "$air_status" ] || [ "$prev_eth_status" != "$eth_status" ]; then
    if [ -f "./statusChanged.sh" ]; then
	"./statusChanged.sh" "$eth_status" "$air_status" &
    fi
fi

# Determine whether ethernet status changed
if [ "$prev_eth_status" != "$eth_status" ]; then

    if [ "$eth_status" = "On" ]; then
	set_airport "Off"
	growl "Wired network detected. Turning AirPort off."
    else
	set_airport "On"
	growl "No wired network detected. Turning AirPort on."
    fi

# If ethernet did not change
else

    # Check whether AirPort status changed
    # If so it was done manually by user
    if [ "$prev_air_status" != "$air_status" ]; then
	set_airport $air_status

	if [ "$air_status" = "On" ]; then
	    growl "AirPort manually turned on."
	else
	    growl "AirPort manually turned off."
	fi

    fi

fi

# Update ethernet status
if [ "$eth_status" == "On" ]; then
    touch /var/tmp/prev_eth_on
else
    if [ -f "/var/tmp/prev_eth_on" ]; then
	rm /var/tmp/prev_eth_on
    fi
fi

exit 0

You will need to make the script executable.  Open Terminal and change the permissions on the script by executing the following command:

chmod 755 /Library/Scripts/toggleAirport.sh

Copy the following xml code into a text document and save as /System/Library/LaunchAgents/com.mine.toggleairport.plist

<?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.asb.toggleairport</string>
  <key>OnDemand</key>
  <true/>
  <key>ProgramArguments</key>
  <array>
    <string>/Library/Scripts/toggleAirport.sh</string>
  </array>
  <key>WatchPaths</key>
  <array>
    <string>/Library/Preferences/SystemConfiguration</string>
  </array>
</dict>
</plist>

You will need to load the plist into your launchctl daemon.  You can do this by opening Terminal and executing the following command:

sudo launchctl load /System/Library/LaunchAgents/com.mine.toggleairport.plist

When I first tried this, I would get the error “Dubious ownership on file (skipping)”.  I changed the ownership on the plist to match other launch agents with the following command and the plist loaded properly into launchctl:

sudo chown root:wheel  /System/Library/LaunchAgents/com.mine.toggleairport.plist

Now when I unplug my Ethernet cable my AirPort turns on and connects to known networks automatically, and when I plug in an Ethernet cable my AirPort turns off. Magic.

UPDATE: I just upgraded my MacBook Pro and monitor. I now have one of the new thunderbolt displays. These displays have an internal PCI Express network interface, so this script will not work properly when using the display’s network interface.  This interface is ‘en3’ so an additional check for this interface is required.  Simply add the following lines of code:

# Check actual current ethernet status for the Display Adapter
if [ "`ifconfig en3 | grep \"status: active\"`" != "" ]; then
    eth_status="On"
fi

I added these lines after the identical lines of code for ‘en0’.

ANOTHER UPDATE:  The new MacBook Pro’s with retina display do not have a built-in Ethernet port. So, the Airport is en0.  If you are using a Thunderbolt to Gigabit Ethernet dongle it appears that the Ethernet port is assigned en1.  You will need to replace en0 with en1 and vice versa in the “toggleAirport.sh” script for this to work, per Daniel’s comment below.  I’m not sure if the Thunderbolt display adapter is universally designated en3, I will update this post when I find out.

ANOTHER UPDATE, 14 September 2012: I just got a new 15″ MBP with retina display and consequently no built in Ethernet. I confirm that the Airport is en0 and the thunderbolt display Ethernet is en1. So, simply swapping the one instance of en0 to en1 and the three instances of en1 to en0 in “toggleAirport.sh” will fix this problem. Make sure the script is executable per above and it will start working as expected, no reboot necessary. I don’t yet have a USB-Ethernet adapter or Thunderbolt-Ethernet adapter, so I don’t know what interface number is assigned for those yet, I’ll report on that when I get my hands on them.

YET ANOTHER UPDATE, 15 April 2015: I’ve had a Thunderbolt Ethernet adapter for a few months now, and like the display adapter it creates another Ethernet interface, in this case en6. I’ve updated the script above and it should work for most people with relatively new MBPs. I still don’t know what interface a USB-Ethernet adapter creates, but the same principle applies, create an if statement to check for that interface. Also, I can’t guarantee that every Mac assigns the Ethernet interfaces in the same order, so you need to check your own work using ifconfig.

21 Comments »

  1. Do you have any bad behavior when taking these steps:1. sleep, 2. remove the ethernet connection, 3. wake from sleep?

    Comment by weking — June 28, 2011 @ 11:42 am

  2. I haven’t found any problems with the way this script behaves with the exception that rarely, very rarely, it simply fails to either turn on or off the airport, or at least it doesn’t do it fast enough for me, and I resort to doing it manually. Most of the time it works fine when resuming from sleep. As it should as it uses a system monitor which checks for changes to the network preferences.

    Comment by kendall — June 28, 2011 @ 2:55 pm

  3. I leave my airport on all of the time. When I am plugged in traffic that is not already connected goes over ethernet because it is ranked higher than my airport. There is no need to turn it on an off unless it’s interfering with your brian waves or something like that. I usually plug in the ethernet cable while it’s still asleep so there are no connections.

    Comment by Joe — September 20, 2011 @ 1:25 pm

  4. Joe, I’m glad you are satisfied with your arrangement. But, I have found that since I scripted this little task, I have had less trouble with applications, like Chrome, freaking out when I switch networks. On an added note, I did not have to do anything when I upgraded to OS X Lion. It just kept working.

    Comment by kendall — September 20, 2011 @ 2:30 pm

  5. Thanks for the post works well for me so far. I noticed a small error in your chown command to fix the dubious ownership error. You dropped the /System/ from the file path. Should be:

    sudo chown root:wheel /System/Library/LaunchAgents/com.mine.toggleairport.plist

    Cheers~

    Comment by jordan — November 1, 2011 @ 8:37 am

  6. Thanks, Jordan. Fixed it.

    Comment by kendall — November 23, 2011 @ 10:58 am

  7. 🙁 Doesn’t work with my MId 2011 MBA and Thunderbolt display, even with the updated lines.

    Comment by Moquette — March 30, 2012 @ 7:36 pm

  8. Moquette,

    Does it work when not using the display ethernet adapter? If not it might be a permissions issue.
    Else, it is possible that your display adapter is not en3. Especially if you are using multiple external thunderbolt displays. Since the script with the added lines only checks for en0 and en3. Check to see if your display adapter is also en3 with an ‘ifconfig’ from the terminal. If the display adapter is turning up with a different number add the lines but substitute the correct interface identifier.

    Comment by kendall — April 2, 2012 @ 8:41 am

  9. […] http://www.georges.nu/blog/2011/06/how-to-automatically-turn-off-airport-when-ethernet-is-plugged-in… […]

    Pingback by For Macbook owners. | www.ionorbit.com — May 7, 2012 @ 9:00 pm

  10. Worked perfectly. Thanks very much for the easy to follow steps. You have helped me to further my quest for complete laziness. LOL! Seriously, thank you.

    Comment by Stephen M — July 18, 2012 @ 10:54 am

  11. Thanks for this! I’m running a new MacBook Pro Retina, and before I read how to get around the “Dubious ownership on file ” on this page, I was stumped! As it turns out, one more change was required to make it work in my case: Airport is en0 and Ethernet is en1, so I had to change 3 occurrences of “en1” to “en0” and one occurrence of “en0” to “en1” in the first script. Once that was done and the rest of the instructions were followed, the things worked (and still works!) like a charm. And yes, that’s using the Thunderbolt to Ethernet adapter. Again, thank you!

    Comment by Daniel — July 18, 2012 @ 1:44 pm

  12. Thanks, Daniel. As coincident would have it, I was just checking out the new MacBook Pro w/retina display at the Apple store and observed that they do not have a built in Ethernet port. This would explain why the Airport is en0. Appreciate your feedback on the post as it will surely help others as more of these new MBPs hit the streets.

    Comment by kendall — July 18, 2012 @ 2:18 pm

  13. While it may not seem necessary to some of you, something like this helps reduce wireless infrastructure costs associated with maintaining enough access points for all the computers in an enterprise. Each access point has limits as to how many wireless clients it can handle well, and idle wireless signals clog up the access points. Therefore this is helpful in conserving our wireless and our budget.

    Comment by Ed — August 7, 2012 @ 9:14 am

  14. Excellent point about wifi congestion. Thanks for contributing.

    Comment by kendall — August 7, 2012 @ 4:23 pm

  15. I stumbled upon your solution when I got my rMBP a month ago and it worked the first day, but it seems like it gets confused a lot lately and does the wrong thing. Now, most of the time it does the opposite of what it did in the past. It turns off Wi-Fi when the computer is woken up without Thunderbolt display connected and it turns Wi-Fi on when the computer is woken up with the display connected.

    Have you noticed this?

    Comment by Andre — January 17, 2013 @ 1:02 pm

  16. Very intermittently I have seen it get confused when it has gone to sleep connected to my Thunderbolt Display but woke up disconnected. Apart from that I can’t say that I’ve had any problems.

    Comment by kendall — January 17, 2013 @ 3:28 pm

  17. Be aware this script causes lots of problems under Mavericks 10.9. It makes Wifi disconnect every ten seconds with error -3093.

    Comment by Bicoid — November 2, 2013 @ 6:04 pm

  18. I’ve upgraded to Mavericks and haven’t had any problems. I don’t have a single error 3093 in my event log. I don’t mind posting in case others are having the same problem.

    Comment by kendall — November 2, 2013 @ 7:54 pm

  19. Great! I found this script but it didn’t include the “load the plist into the daemon” part and I was wondering why it wasn’t working.

    For any future people to stumble upon this and wonder why you would want to automatically disable the airport, for me its because it continually asks me about accepting certificates, and then asks for credentials and the like with such perfect timing that as soon as I click the icon and go to turn off wifi, another message pops up stealing focus. Quite a nuisance!

    Thanks again, kendall for the update for Mavericks.

    Comment by Aric — November 18, 2013 @ 1:41 pm

  20. I can confirm i am using mac osx 10.9.2 and tghe script works without any modifications. i have wifi, ethernet, firewire, bluetooth, theunderbird.

    Comment by sharif — March 12, 2014 @ 9:15 am

  21. Thanks!

    Comment by kendall — March 12, 2014 @ 3:24 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress