Ubuntu標準のnmcliコマンドで特定のWiFi APをモニターする

「[Ubuntu標準コマンドでWiFiの状態を確認する](967152c65cbda97dadce)」で`nmcli`コマンドを使えばAPの情報を得られることがわかったので、今回は特定のAPを`ping`みたいな感じでモニターしてみたいと思います。今回、使った環境はUbuntu16のEnglish（en_US）の標準インストール状態です。

## 現状を確認する
まず`nmcli`コマンドで現状のWiFiの状態を確認します。我が家では以下のような感じです（※ご近所APとかの関係で一部のSSIDをマスクしています）。

```console:
$ nmcli dev wifi
*  SSID                              MODE   CHAN  RATE       SIGNAL  BARS  SECURITY  
*  LAPUTA                            Infra  1     54 Mbit/s  89      ▂▄▆█  WPA2       
   000000000000-2G                   Infra  11    54 Mbit/s  44      ▂▄__  WPA1 WPA2 
   WARPSTAR-000000                   Infra  3     54 Mbit/s  40      ▂▄__  WPA1 WPA2 
   LAPUTA                            Infra  6     54 Mbit/s  34      ▂▄__  WPA2        
   Buffalo-G-0000                    Infra  1     54 Mbit/s  30      ▂___  WPA1 WPA2 
   WARPSTAR-000000-W                 Infra  3     54 Mbit/s  22      ▂___  WEP       
   perseus                           Infra  8     54 Mbit/s  22      ▂___  WPA2      
   LAPUTA                            Infra  11    54 Mbit/s  20      ▂___  WPA2         
   Buffalo-A-0000                    Infra  120   54 Mbit/s  14      ▂___  WPA1 WPA2 

```

「LAPUTA」というSSIDのAPが私の管理しているもので3台あります。今回はちょっと遠方においてあると思われる2つめの「LAPUTA」を追いかけてみようと思います。

「2つめ」といっても電波の強さで勝手に順序は変わってしまいますし、といってチャンネル番号も何となく危うい気がします。そういった中で比較的変わりにくい（たぶん変わらないであろう）情報としてBSSIDというのがあります。
BSSIDを表示するには`-f`オプションでBSSIDを指定します。その結果が以下のとおりです。

```console:
$ nmcli -f IN-USE,SSID,BSSID,CHAN,SIGNAL,BARS,SECURITY dev wifi
*  SSID               BSSID              CHAN  SIGNAL  BARS  SECURITY  
*  LAPUTA             00:00:00:00:00:30  1     91      ▂▄▆█  WPA2       
   000000000000-2G    00:00:00:00:00:00  11    45      ▂▄__  WPA1 WPA2 
   WARPSTAR-000000    00:00:00:00:00:00  3     42      ▂▄__  WPA1 WPA2 
   LAPUTA             00:00:00:00:00:10  6     34      ▂▄__  WPA2        
   Buffalo-G-0000     00:00:00:00:00:00  1     30      ▂___  WPA1 WPA2 
   WARPSTAR-000000-W  00:00:00:00:00:00  3     22      ▂___  WEP       
   perseus            00:00:00:00:00:00  8     22      ▂___  WPA2      
   LAPUTA             00:00:00:00:00:21  11    20      ▂___  WPA2         
   Buffalo-A-0000     00:00:00:00:00:00  120   14      ▂___  WPA1 WPA2 
```

表示させてみるとSSIDは一緒でもBSSIDは異なっていることがわかります。このBSSIDを使えばターゲットにしたいAPを特定することができそうです。

## まずはシンプルに
まずはシンプルにBSSIDが00:00:00:00:00:10のAPを追跡するスクリプトです。

```bash:シンプル版
#!/bin/sh

while true; do
	nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,BARS dev wifi list bssid 00:00:00:00:00:10 | tail -1
	sleep 1
done
```

結果は以下のようになります。もともと`ping`のような結果をイメージしていたのですが、結果があまりにも変わらないので思ったよりも面白くない結果となりました。

```text:
LAPUTA   00:00:00:00:00:10  11    2462 MHz  77      ▂▄▆_ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  79      ▂▄▆_ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  79      ▂▄▆_ 
```

## ワンライナーで書く
これくらいの短さならワンライナーでもなんとか書けます。以下のような感じです。ファイルを作らなくてもコピー＆ペーストで使えるのは案外と重宝したりします。

```bash:ワンライナー版
$ while sleep 1;do nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,BARS dev wifi list bssid 00:00:00:00:00:10 | tail -1;done
```

## 列名を表示する
列名がなくてもなんとなく分かるのですが、それでは嫌という場合です。一番はじめだけ2行表示して後は1行だけ表示しているだけです。

```bash:列名を表示する
show_lines=2
while true; do
    nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,BARS dev wifi list bssid 00:00:00:00:00:10 | tail -$show_lines
    [ "$show_lines" = "2" ] && show_lines=1
    sleep 1
done
```

```text:
SSID     BSSID              CHAN  FREQ      SIGNAL  BARS
LAPUTA   00:00:00:00:00:10  11    2462 MHz  77      ▂▄▆_ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  88      ▂▄▆█ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  79      ▂▄▆_ 
LAPUTA   00:00:00:00:00:10  11    2462 MHz  79      ▂▄▆_ 
```

## 先頭に日時を付ける
以前「[pingに日時（タイムスタンプ）をつける](727f7388b0f01ad1d631)」でpingに日時を付けたことがあったので、その応用です。ちょっと横に長くなるので`sed`を使ってスペースを圧縮しています。

```bash:日時をつける
#!/bin/sh

while true; do
	nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,BARS dev wifi list bssid 00:00:00:00:00:10 | tail -1 |\
	sed -r 's/ +/ /g' |\
	xargs -I_ date +'%F %T _'
	sleep 1
done
```

結果は以下のような感じになります。

```text:
2018-08-09 08:23:42 LAPUTA 00:00:00:00:00:10 11 2462 MHz 86 ▂▄▆█ 
2018-08-09 08:23:44 LAPUTA 00:00:00:00:00:10 11 2462 MHz 86 ▂▄▆█ 
2018-08-09 08:23:45 LAPUTA 00:00:00:00:00:10 11 2462 MHz 86 ▂▄▆█ 
2018-08-09 08:23:47 LAPUTA 00:00:00:00:00:10 11 2462 MHz 86 ▂▄▆█ 
2018-08-09 08:23:48 LAPUTA 00:00:00:00:00:10 11 2462 MHz 93 ▂▄▆█ 
2018-08-09 08:23:49 LAPUTA 00:00:00:00:00:10 11 2462 MHz 93 ▂▄▆█ 
2018-08-09 08:23:51 LAPUTA 00:00:00:00:00:10 11 2462 MHz 93 ▂▄▆█ 
```

## シグナルの強さで色をつける
シグナルの強さで色を変えたい時は`nmcli`コマンドに`-c yes`オプションを追加します。

```bash:シグナルの強さで色付け
#!/bin/sh

while true; do
	nmcli -c yes -f SSID,BSSID,CHAN,FREQ,SIGNAL,BARS dev wifi list bssid 00:00:00:00:00:10 | tail -1 |\
	sed -r 's/ +/ /g' |\
	xargs -I_ date +'%F %T _'
	sleep 1
done
```

先ほどの書き方では残念ながら日時には色がつきません。日時にも色がつかなくちゃ嫌だという場合は、力任せで色を付けちゃうという手もあります。力任せと言えば力任せなんですが、自分好みの色を付けられたり、色々と応用が効くのでそれはそれで良い所もあったりもします。

```bash:日時にも色付け
#!/bin/sh

while true; do
	nmcli -c yes -f SSID,BSSID,CHAN,FREQ,SIGNAL,BARS dev wifi list bssid 00:00:00:00:00:10 | tail -1 |\
	sed -r 's/ +/ /g' |\
	xargs -I_ date +'%F %T _' |\
	GREP_COLOR='32' egrep --color=always '.*▂▄▆█|$' |\
	GREP_COLOR='33' egrep --color=always '.*▂▄▆_|$' |\
	GREP_COLOR='35' egrep --color=always '.*▂▄__|$' |\
	GREP_COLOR='36' egrep --color=always '.*▂___|$'
	sleep 1
done
```