Shell script to monitor network on MacOS
Tags: bash, mac, speedtest, geektool
Published: 2020-11-02 11:17:56

---
title: Shell script to monitor network on MacOS
published: true
description: 
tags: bash, Mac, speedtest, geektool
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/f3lpxj8fqpxzhxyt89d6.png
---

## TL;DR

In the context of a global pandemic, more and more people are working from home. In software development, it can be important to know which network to access from, or network speed for a comfortable video conference. It's useful to have a quick check on such things.

I'd like to be able to look up

- Outgoing IP Address
- Internal IP Address
- The Wi-Fi SSID
- Network Speed DL/UL

with bash script.
And I'd like to display it on the desktop with Geektool, which may not be used by many people these days.
If you just want to see the results, skip all of them and go to github.

[kurab/networkMonitorMac](https://github.com/kurab/networkMonitorMac)

## Environments

- Mac Pro (late 2013) / macOS Catalina version 10.15.7
- MacBook Air 2020 / macOS Catalina version 10.15.7


## Outgoing IP Address

When connecting to a protected network based on a reliable, fixed IP address, it's important to know your external IP address.

You can get it with following command.

```
$ curl --silent api.ipify.org --max-time 5
```

So, the script will be like this:

```bash
#!/bin/bash
ext_info=`curl --silent api.ipify.org --max-time 5`

wait

if [ -n "$ext_info" ];
then
    echo "External: $ext_info"
else
    echo "External: OFFLINE"
fi

unset ext_info
```

"wait" may not be necessary, but we'll put it in from the beginning later, as there's heavy processing involved.



## Internal IP Address

First, find out the MAC address of your Wi-Fi adapter.

Go to Preferences > Network and select Wi-Fi, click Advanced to display Hardware and remember the MAC Address. Just remember the last two letters or so.

```
$ ifconfig
```

When you hit this command, you'll see a list of things, but try looking for sections like en0: en1: en2: ... In the "ether" section, you can see something like the MAC Address, so look for the MAC Address of the Wi-Fi.

In my case, en2 for Mac Pro and en0 for MacBook Air. The explanation continues with en0.

The IP address of the assigned network is written in en0 of ifconfig, so I extract it.

```bash
#!/bin/bash
en0_info=`ifconfig en0 | grep inet | grep netmask | grep -v 127.0.0.1 | awk '{print $2}'`

wait

if [ -n "$en0_info" ];
then
    echo "Wi-Fi: $en0_info"
else
    echo "Wi-Fi: INACTIVE"
fi

unset en0_info
```


## SSID

On MacOS, you can learn a lot of things about Wi-Fi by typing the following command, which was the same on pre-Catalina OSes.


```
$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I
```

The SSID is the information you want to know. You can get various other information as well, so please scatter what you need as needed.

```bash
#!/bin/bash
en0_info=`ifconfig en0 | grep inet | grep netmask | grep -v 127.0.0.1 | awk '{print $2}'`

wait

if [ -n "$en0_info" ];
then
    wifi_network=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F: '/ SSID: / {print $2}' | sed -e 's/.*SSID: //'`


    echo "Wi-Fi: $en0_info"
    echo "- SSID: $wifi_network"

    unset wifi_network
else
    echo "Wi-Fi: INACTIVE"
fi

unset en0_info
```


## Network Speed DL/UL

Use speedtest-cli to measure the network speed.

- [SPEEDTEST CLI](https://www.speedtest.net/apps/cli)
- [speedtest-cli](https://pypi.org/project/speedtest-cli/)

It's a bit different in function, but either one is fine. This time, I'll use the latter one, pypi's. I'd like to get it with curl and put it in /usr/local/bin.

```
$ curl -Lo speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py
$ chmod +x speedtest-cli
$ mv speedtest-cli /usr/local/bin/.
```

versions:

```
$ speedtest-cli --version
speedtest-cli 2.1.2
Python 3.8.3 (default, Jul  2 2020, 11:26:31) [Clang 10.0.0 ]
```

If you switch to a Python version, such as 3.9.0, the following will still work.

```
$ speedtest-cli --simple
```

You'll see that it takes quite a bit of time to measure. The code we've been using so far will give you instantaneous results of execution, so if it's annoying, you can separate the scripts.

```
$ speedtest-cli --simple | grep Download | awk '{print $2}'
```

You can get it like this, but this is not practical because you have to measure twice with DL/UL, which takes a crazy amount of time. Let's use the measurement once and use it well.

```bash
#!/bin/bash
speed_info=`/usr/local/bin/speedtest-cli --simple 2>/dev/null | grep load | sed -e 's/^.*: //g;s/ M.*$//g'`

wait

if [ -n "$speed_info" ];
then
    dl_speed=`echo $speed_info | awk '{print $1}'`
    ul_speed=`echo $speed_info | awk '{print $2}'`

    echo "Download: $dl_speed Mbps"
    echo "Upload: $ul_speed Mbps"

    unset speed_info
    unset dl_speed
    unset ul_speed
else
    echo "Download: -"
    echo "Upload: -"
fi
```

speedtest-cli spits out a standard error if you're not connected to the network. I discarded it. "Mbps" is fixed. We'll think about it again when the network is much faster.


## LAN cable?!

There may be a case that you are not using Wi-Fi but LAN cable to connect to the Internet. The way to check the network interface is the same. This time, en0 in Mac Pro and MacBook Air do not have the interface of LAN cable, but it is possible to use it via the adapter of USB-C. In that case, it was en2.

In the explanation.

- Wi-Fi: en0
- LAN: en2

In the case of a LAN, set only the IP address in the network.

```bash
#!/bin/bash
en2_info=`ifconfig en2 |grep inet |grep netmask |grep -v 127.0.0.1 |awk '{print $2}'`

wait

if [ -n "$en2_info" ];
then
    echo "Ethernet: $en2_info"
else
    echo "Ethernet: INACTIVE"
fi

unset en2_info
```


## Final Source Code

Put all of the above together and adjust the spaces and so on, the source code will look like this


```bash
#!/bin/bash
speed_info=`/usr/local/bin/speedtest-cli --simple | grep load | sed -e 's/^.*: //g;s/ M.*$//g'`

ext_info=`curl --silent api.ipify.org --max-time 5`

en0_info=`ifconfig en0 | grep inet | grep netmask | grep -v 127.0.0.1 | awk '{print $2}'`
en2_info=`ifconfig en2 | grep inet | grep netmask | grep -v 127.0.0.1 | awk '{print $2}'`

wait

if [ -n "$speed_info" ];
then
    dl_speed=`echo $speed_info | awk '{print $1}'`
    ul_speed=`echo $speed_info | awk '{print $2}'`

    echo "Download   : $dl_speed Mbps"
    echo "Upload     : $ul_speed Mbps"

    unset speed_info
    unset dl_speed
    unset ul_speed
else
    echo "Download   : -"
    echo "Upload     : -"
fi

echo ""

if [ -n "$ext_info" ];
then
    echo "External   : $ext_info"
else
    echo "External   : OFFLINE"
fi

unset ext_info

if [ -n "$en0_info" ];
then
    wifi_network=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F: '/ SSID: / {print $2}' | sed -e 's/.*SSID: //'`


    echo "Wi-Fi      : $en0_info"
    echo "- SSID     :$wifi_network"

    unset wifi_network
else
    echo "Wi-Fi      : INACTIVE"
fi

unset en0_info

if [ -n "$en2_info" ];
then
    echo "Ethernet   : $en2_info"
else
    echo "Ethernet   : INACTIVE"
fi

unset en2_info
```

executed result is like this

```
$ ./networkmonitor.sh
Download   : 37.69 Mbps
Upload     : 54.78 Mbps

External   : XXX.XXX.XXX.XXX
Wi-Fi      : 192.168.1.19
- SSID     : XXXXXXXXXXXXXXX
Ethernet   : INACTIVE
```

## Configure Geektool

Refresh for 120 seconds, time out for 60 seconds, set Font to Ricty and run this bash script, oh my goodness! On my desktop, at all times!

![Network Monitoring on Desktop](https://dev-to-uploads.s3.amazonaws.com/i/f3lpxj8fqpxzhxyt89d6.png)

The network speed isn't very nice tho...