Search code examples
terminalsystem-profilergeektool

Need help using GeekTool with system_profiler and networksetup


Aloha everyone,

I have created a small bash shell script which I wanted to use with GeekTool, but I have experienced different results using the same script on my iMac (11,1) and my MacBook Pro (8,3). I'm pulling network data using both networksetup and system_profiler. What I have thus far are several calls to both, but would like to consolidate it to one call to each process creating variables to use in my script. Here is my script thus far:

# Get Ethernet and Wi-Fi information and display it for GeekTool
WiFi=$(networksetup -getairportnetwork en1 | awk '{print $4 " " $5 " " $6 " " $7 " " $8}')
WiFi_IP=$(networksetup -getinfo Wi-Fi | grep -v IPv6 | awk '/IP address/ {print $3}')
SubMask=$(networksetup -getinfo Wi-Fi | awk '/Subnet mask/ {print $3}')
S2N=$(system_profiler SPAirPortDataType | awk '/Noise/ {print $4 " " $5 " " $6 " " $7 " " $8}')
TRate=$(system_profiler SPAirPortDataType | awk '/Rate/ {print $3 " Mbps"}')
echo  -e "\033[4;33m" AirPort

if [ "$WiFi_IP" = "" ];
    then echo "Not connected to wireless AP."
    else echo -e "Wi-Fi AP: " $WiFi "\nIP Address: " $WiFi_IP "\nSubnet Mask: " $SubMask "\nTransmit Rate: " $TRate
    fi

EthIP=$(networksetup -getinfo Ethernet | grep -v IPv6 | awk '/IP address/ {print $3}')
EthSubMask=$(networksetup -getinfo Ethernet | grep -v IPv6 | awk '/Subnet mask/ {print $3}')
echo -e "\033[4;33m" "\nEthernet"

if [ "$EthIP" = "" ];
    then echo "Not connected to wired network."
    else echo -e "IP Address: " $EthIP "\nSubnet Mask: " $EthSubMask
    fi

When I create a shell in GeekTool and enter the path to my script, everything works fine on my MacBook Pro, but on my iMac, GeekTool displays the results fine once, then upon the refresh (I had it set for 15s), the result disappear and never returns to the screen. While I know that what I have works, it makes too many calls to both processes and I would like to consolidate it to one call per process, extracting the desired information into a container such as an array from which I can access said desired information.

In other words, does anyone know how I can make just one call to networksetup to get all the information gathered from both -getairportnetwork en1 and -getinfo Wi-Fi as well as system_profiler SPAirPortDataType (which takes the longest - around 5-8 seconds each time)?


Solution

  • I modified my geek tool script a little bit and omitted the Signal to Noise ration thing. Here is what the new AirportStatus.sh file looks like:

    #! /bin/bash
    
    # echo -e "\033[0;30m"       echo in black
    # echo -e "\033[0;31m"       echo in red
    # echo -e "\033[0;32m"       echo in green
    # echo -e "\033[0;33m"       echo in yellow
    # echo -e "\033[0;34m"       echo in blue
    # echo -e "\033[0;35m"       echo in magenta
    # echo -e "\033[0;36m"       echo in cyan
    # echo -e "\033[0;37m"       echo in white
    
    # echo -e "\033[4;37m"       echo in white underlined
    
    echo -e "\033[4;33m" "Airport"
    
    # Get Airport status from OS X
    Status=$(ifconfig en1 | awk '/status/ {print $2}')
    
    
    if [ "$Status" = "inactive" ];
        then echo -e "\033[0;31m" "Status: " $Status "\nNot connected to wireless AP."
        else echo -e  "\033[0;32m" "Status" $Status
    
        # Get wireless stats from OS X
    
        WiFi=$(networksetup -getairportnetwork en1 | awk '{print $4 " " $5 " " $6 " " $7 " " $8}')
        WiFi_IP=$(networksetup -getinfo Wi-Fi | grep -v IPv6 | awk '/IP address/ {print $3}')
        SubMask=$(networksetup -getinfo Wi-Fi | awk '/Subnet mask/ {print $3}')
        TRate=$(system_profiler SPAirPortDataType | awk '/Transmit/' | sed 's/[^0-9]//g')
    
        # Get bytes in/out
    
        # get the current number of bytes in and bytes out
        myvar1=$(netstat -ib | grep -e en1 -m 1 | awk '{print $7}') #  bytes in
        myvar3=$(netstat -ib | grep -e en1 -m 1 | awk '{print $10}') # bytes out
    
        #wait one second
        sleep 1
    
        # get the number of bytes in and out one second later
        myvar2=$(netstat -ib | grep -e en1 -m 1 | awk '{print $7}') # bytes in again
        myvar4=$(netstat -ib | grep -e en1 -m 1 | awk '{print $10}') # bytes out again
    
        # find the difference between bytes in and out during that one second
        subin=$(($myvar2 - $myvar1))
        subout=$(($myvar4 - $myvar3))
    
        # convert bytes to megabytes
        mbin=$(echo "scale=2 ; $subin/1048576;" | bc) 
        mbout=$(echo "scale=2 ; $subout/1048576 ; " | bc)
    
        usedMB=$(echo "scale=2 ; $mbin+$mbout ; " | bc)
        AvailBW=$(echo "scale=2 ; $TRate-$usedMB ; " | bc)
    
        echo -e "\033[0;37m" "Wi-Fi AP: " "\033[0;36m" $WiFi "\033[0;37m" "\nIP Address: " "\033[0;36m" $WiFi_IP $3 "\033[0;37m" "\nSubnet Mask: " "\033[0;36m" $SubMask "\033[0;37m" "\nTransmit Rate: " "\033[0;36m" $TRate " Mbps\n" "\033[0;37m" "Data In: "  "\033[0;36m" $mbin "Mbps" "\n" "\033[0;37m" "Data Out: "  "\033[0;36m" $mbout "Mbps\n" "\033[0;37m" "Available Bandwidth: " "\033[0;36m" $AvailBW " Mbps"
    
        fi
    

    I checked the for active status, assuming that it was initially inactive. If not, then I put in the massive if statement where all the variables are initialized and the computations are done. There is only one call to system_profiler, the one that retrieves the transmission rate, but I wanted to see the "line speed" of my wireless network. This works, not as well as I would have liked, but it was still a good exercise in learning a little bit about where to get information on my Mac, and how to use both awk and see. I still have a lot to learn, but this has been exciting thus far.