How to determine the nss (number of spatial streams) via MACOS cli

Viewed 206

On a MACOS (MacBook Pro) I'm trying to determine a way to derive the number of wifi spatial streams via cli. The terminal command to produce wifi details is: /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I

...but nss is not part of the details produced.

The nss seems to be only visible via GUI by holding down the option key and clicking on the wifi icon.

The goal is to add it to my BASH script.

2 Answers

plutil is a tool to read plist file (- for STDIN), and print it in another format or extract partial information from it.

Examples:

Convert to JSON

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I -x \
| plutil -convert json - -o -
{...,"NSS":2,...}

Extract one key

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I -x \
| plutil -extract NSS raw -
2

If you add the -x flag to the airport utility, you get XML output which is more verbose:

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I -x

Sample Output

<?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>AUTH_LOWER</key>
    <integer>1</integer>
    <key>AUTH_UPPER</key>
    <integer>8</integer>
    <key>BANDWIDTH</key>
    <integer>80</integer>
    <key>CHANNEL</key>
    <integer>100</integer>
    <key>CHANNEL_FLAGS</key>
    <integer>1040</integer>
    <key>GI</key>
    <integer>400</integer>
    <key>MCS_INDEX</key>
    <integer>3</integer>
    <key>NOISE_CTL_AGR</key>
    <integer>-93</integer>
    <key>NOISE_UNIT</key>
    <integer>0</integer>
    <key>NSS</key>                    <--- HERE IT IS
    <integer>3</integer>
    <key>RSSI_CTL_AGR</key>
    <integer>-60</integer>
    <key>RSSI_CTL_LIST</key>
    <array>
        <integer>-61</integer>
        <integer>-57</integer>
        <integer>-62</integer>
    </array>
    <key>RSSI_EXT_AGR</key>
    <integer>0</integer>
    <key>RSSI_EXT_LIST</key>
    <array>
        <integer>0</integer>
        <integer>0</integer>
        <integer>0</integer>
    </array>
    <key>RSSI_UNIT</key>
    <integer>0</integer>
</dict>
</plist>

You can direct that to a file then parse the file with PlistBuddy - though there may be a more elegant way I don't know (ping me if anyone does):

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I -x > /tmp/airport.plist

/usr/libexec/PlistBuddy /tmp/airport.plist -c "Print :NSS"
3

It seems PlistBuddy refuses to read from anything other than a real, solid file and will not accept bash "proces substitution" as an input... so, the only solution I can work out that doesn't use a temporary file is this:

airport -I -x | awk '/<key>NSS<\/key>/{getline; gsub(/[^0-9]/,""); print; exit}'

UPDATE

I have worked out a way to do it reliably, as a one-liner, without an intermediate file using Python. The plistlib module is in the standard Python library, so nothing to install :-)

airport -I -x | python3 -c 'import plistlib, sys; pl=plistlib.loads(sys.stdin.buffer.read()); print(pl["NSS"])'

Keywords: macOS, wifi, wi-fi, airport, airport utility, NSS, spatial streams, command-line, commandline, CLI, XML, PlistBuddy, plistlib.

Related