Posted on 07-09-2015 06:46 AM
The additional character in 10.10 has broken another script we use, but I'm not sure how to fix this one due to my limited scripting skills. I tried to remove the if statements referring to OS type since we have nothing older than 10.7 in use, and even they will be gone shortly, but I just ended up breaking the script in different ways.
The unmodified script that breaks on 10.10:
#!/bin/bash
AP_NAME="NETWORK"
AP_SEC="WPA2E"
INDX=0
AIRPORT=""
ALLINTERFACES=""
IFS='
'
SW_VER=`/usr/bin/sw_vers -productVersion`
if [ `echo "if(${SW_VER%.*}>=10.7)r=1;r"|/usr/bin/bc` -eq 1 ]; then
APNAME="Wi-Fi"
else
APNAME="AirPort"
fi
#
# Look for AirPort interface
#
for intf in `/usr/sbin/networksetup -listnetworkserviceorder | grep "^(H"`; do
IFS=':,)'
set $intf
if [[ ($2 =~ ${APNAME} ) ]]; then AIRPORT=$4; fi
done
if [ `echo "if(${SW_VER%.*}>=10.6)r=1;r"|/usr/bin/bc` -eq 1 ]; then
RM_AP_CMD="/usr/sbin/networksetup -removepreferredwirelessnetwork ${AIRPORT} ${AP_NAME}"
ADD_AP_CMD="/usr/sbin/networksetup -addpreferredwirelessnetworkatindex ${AIRPORT} ${AP_NAME} ${INDX} ${AP_SEC}"
else
RM_AP_CMD="/usr/sbin/networksetup -removepreferredwirelessnetwork ${APNAME} ${AP_NAME}"
ADD_AP_CMD="/usr/sbin/networksetup -addpreferredwirelessnetworkatindex ${APNAME} ${AP_NAME} ${INDX} ${AP_SEC}"
fi
# Remove Existing WiFi Profile
profileTest=$(/usr/bin/profiles -C -v | /usr/bin/awk -F: '/profileIdentifier: com.domain.network/{print $NF}')
if [ -n "$profileTest" ]; then
echo "Found WiFi Profile installed."
echo "Removing existing WiFi Profile"
/usr/bin/profiles -R -v -p com.domain.network -z Tw0wMQWKy123
fi
# Remove Wireless LAN from Preferred List
echo "Removing Wireless LAN $AP_NAME from Preferred List"
eval ${RM_AP_CMD}
# Add Wireless LAN to the Preferred List
echo "Adding Wireless LAN $AP_NAME to Preferred List"
eval ${ADD_AP_CMD}
Thanks for any tips and guidance!
-Bob
Solved! Go to Solution.
Posted on 07-09-2015 08:41 AM
@rlindenmuth While you could add the code that @pwskura shows above, the only reason for even getting the OS version is because 10.6 and lower referred to wireless as "AirPort" and 10.7 and up changed it to "Wi-Fi" Because the script you're using is trying to manipulate the preferred wireless entries using the wi-fi port name instead of the device id, its required to go through all that to work. But I contend its not even necessary. You can try something like this below. What I'm doing here is figuring out what either the AirPort or Wi-Fi device id is, like en0 or en1 and using that instead, which is more reliable.
#!/bin/bash
AP_NAME="NETWORK"
AP_SEC="WPA2E"
## Simple one liner to get the device id for the Wireless port, i.e, en0 or en1, etc.
WirelessPort=$(/usr/sbin/networksetup -listallhardwareports | awk -F': ' '/AirPort|Wi-Fi/{getline; print $NF}')
## Remove Existing WiFi Profile
profileTest=$(/usr/bin/profiles -C -v | /usr/bin/awk -F: '/profileIdentifier: com.domain.network/{print $NF}')
if [ -n "$profileTest" ]; then
echo "Found WiFi Profile installed."
echo "Removing existing WiFi Profile"
/usr/bin/profiles -R -v -p com.domain.network -z Tw0wMQWKy123
fi
## Remove Wireless LAN from Preferred List
echo "Removing Wireless LAN $AP_NAME from Preferred List"
/usr/sbin/networksetup -removepreferredwirelessnetwork ${WirelessPort} "${AP_NAME}"
## Add Wireless LAN to the Preferred List
echo "Adding Wireless LAN $AP_NAME to Preferred List"
/usr/sbin/networksetup -addpreferredwirelessnetworkatindex ${WirelessPort} "${AP_NAME}" 0 ${AP_SEC}
This script should basically do the same thing as your original one, but is much simpler.
Posted on 07-09-2015 07:10 AM
These two lines are the issue:
if [ `echo "if(${SW_VER%.*}>=10.7)r=1;r"|/usr/bin/bc` -eq 1 ]; then
and
if [ `echo "if(${SW_VER%.*}>=10.6)r=1;r"|/usr/bin/bc` -eq 1 ]; then
In both cases its using bc (bash calculator) to compare the base OS version, in this case 10.10, against either 10.7 or 10.6 to see if its equal or greater to those respective values. The thing is, bc handles decimal numbers, so it sees 10.10 as just 10.1. Obviously 10.1 is not equal or greater to 10.6 or 10.7, so its setting some variables incorrectly (under 10.6, the Wi-Fi network was called "AirPort") and the rest of the script fails.
If you only need to use this script against Macs that are at OS X 10.7 and up, I don't see any need for either of these parts of the script. The whole script could be simplified if you have pretty recent OS X versions you manage.
Posted on 07-09-2015 08:03 AM
I tried to remark those out earlier but kept getting failures. I've removed all if statements and all lines referring to versions prior to 10.7 and this is the error:
Script result: Removing Wireless LAN NETWORK from Preferred List
Wi-Fi is not a Wi-Fi interface.
Error: Error obtaining wireless information.
Adding Wireless LAN NETWORK to Preferred List
Wi-Fi is not a Wi-Fi interface.
Error: Error obtaining wireless information.
I believe those errors are occurring when these lines are run in the script:
RM_AP_CMD="/usr/sbin/networksetup -removepreferredwirelessnetwork ${APNAME} ${AP_NAME}"
ADD_AP_CMD="/usr/sbin/networksetup -addpreferredwirelessnetworkatindex ${APNAME} ${AP_NAME} ${INDX} ${AP_SEC}"
I'm going to need to rewrite it from scratch to cut out the extraneous stuff. It will be a good way to better understand scripting as well.
Posted on 07-09-2015 08:14 AM
Bob, Here is a snippet that just splits the version string to make the math work:
#!/bin/sh
known_os="10" # highest OS minor release supported, 10.10
bottom_os="5" # lowest OS minor release supported, 10.5
#
# Get OS version and exit for unsupported releases
#
os_major=$(sw_vers -productVersion | awk -F '.' '{print $1}')
os_minor=$(sw_vers -productVersion | awk -F '.' '{print $2}')
if [[ "${os_minor}" -lt "${bottom_os}" || "${os_minor}" -gt "${known_os}" ]]; then
printf "unsupported os $os_major.$os_minor
"
exit 1
fi
printf "OS version is $os_major.$os_minor
"
Enjoy!
-Pete
Posted on 07-09-2015 08:41 AM
@rlindenmuth While you could add the code that @pwskura shows above, the only reason for even getting the OS version is because 10.6 and lower referred to wireless as "AirPort" and 10.7 and up changed it to "Wi-Fi" Because the script you're using is trying to manipulate the preferred wireless entries using the wi-fi port name instead of the device id, its required to go through all that to work. But I contend its not even necessary. You can try something like this below. What I'm doing here is figuring out what either the AirPort or Wi-Fi device id is, like en0 or en1 and using that instead, which is more reliable.
#!/bin/bash
AP_NAME="NETWORK"
AP_SEC="WPA2E"
## Simple one liner to get the device id for the Wireless port, i.e, en0 or en1, etc.
WirelessPort=$(/usr/sbin/networksetup -listallhardwareports | awk -F': ' '/AirPort|Wi-Fi/{getline; print $NF}')
## Remove Existing WiFi Profile
profileTest=$(/usr/bin/profiles -C -v | /usr/bin/awk -F: '/profileIdentifier: com.domain.network/{print $NF}')
if [ -n "$profileTest" ]; then
echo "Found WiFi Profile installed."
echo "Removing existing WiFi Profile"
/usr/bin/profiles -R -v -p com.domain.network -z Tw0wMQWKy123
fi
## Remove Wireless LAN from Preferred List
echo "Removing Wireless LAN $AP_NAME from Preferred List"
/usr/sbin/networksetup -removepreferredwirelessnetwork ${WirelessPort} "${AP_NAME}"
## Add Wireless LAN to the Preferred List
echo "Adding Wireless LAN $AP_NAME to Preferred List"
/usr/sbin/networksetup -addpreferredwirelessnetworkatindex ${WirelessPort} "${AP_NAME}" 0 ${AP_SEC}
This script should basically do the same thing as your original one, but is much simpler.
Posted on 07-09-2015 10:22 AM
@mm2270 That worked perfectly! Thank you. This board is fantastic.
Posted on 07-09-2015 09:54 PM
Unix, theres always 42 ways to do the same thing better
Posted on 07-10-2015 07:34 AM
Yeah, I got pretty board with trying to call interfaces and port names and so bothered to write a python script to pump it into a plist. This way all scripts requiring this kind of info can just call this script and then read the plist.
#!/usr/bin/env python
# plistlib is outdated, but we are only writing to this file with this script so it does not matter
# that it will not work with binary files.
# https://github.com/wooster/biplist
from SystemConfiguration import *
import plistlib
import os
import glob
interface_dict = {}
interface_list = []
plist_file = "/Library/Preferences/yourdomain.networklist.plist"
for interface in SCNetworkInterfaceCopyAll():
interface_name = SCNetworkInterfaceGetLocalizedDisplayName(interface)
hw_addr = SCNetworkInterfaceGetBSDName(interface)
if interface_name == "Ethernet 1":
interface_name = "Ethernet"
if interface_name == "Wi-Fi":
interface_name = "AirPort"
interface_dict[interface_name] = hw_addr
interface_list.append(hw_addr)
interface_dict["Ports"] = interface_list
plistlib.writePlist(interface_dict, plist_file)
This will pump out something like the following into /Library/Preferences/yourdomain.networklist.plist
Subsequently, all scripts can then just run 'defaults' to read this and the names will be the same regardless of OS.
MacBookPro Retina (with Ethernet adaptor connected):
{
AirPort = en0;
"Bluetooth DUN" = "Bluetooth-Modem";
"Bluetooth PAN" = en4;
Ports = (
"Bluetooth-Modem",
en3,
en0,
en4,
en1,
en2,
bridge0
);
"Thunderbolt 1" = en1;
"Thunderbolt 2" = en2;
"Thunderbolt Bridge" = bridge0;
"Thunderbolt Ethernet" = en3;
}
MacPro:
{
AirPort = en2;
"Bluetooth DUN" = "Bluetooth-Modem";
"Bluetooth PAN" = en3;
Ethernet = en0;
"Ethernet 2" = en1;
FireWire = fw0;
Ports = (
"Bluetooth-Modem",
en0,
en1,
fw0,
en2,
en3
);
}
Just change, add other if statements if you want to rename anything else.