Ubuntu 標準コマンドで WiFi の状態を確認する

これまで WiFi の状況を知りたいと思った時はアナライザーを探してインストールしてという感じだったのですが、そんなことしなくても標準コマンドで WiFi の状態を確認できる事を知ったので、そのメモです。

## 使うコマンドは？
今回は `nmcli` コマンドで WiFi の状態を確認し、リアルタイムに表示するために`tput`コマンドを使います。私の手元のどの Ubuntu にも `nmcli` コマンドは入っていたのですが、はいっていない場合は network-manager というパッケージをインストールしないといけないようです。

## 実際に `nmcli` コマンドを使ってみる。
以下のように使うと WiFi の状態を確認できます。

```console:
$ nmcli dev wifi
```

結果は以下のとおりです（※ SSID はちょっとマスクしています）。今回は Ubuntu16 で LANG=en_US.UTF-8, LANGUAGE=en_US の環境で実行したもので、実際の画面ではシグナルの強さによって色分けもされて表示されるのですが、そのあたりは OS のバージョンや言語環境によって異なるようです。

```console:
$ nmcli dev wifi
*  SSID               MODE   CHAN  RATE       SIGNAL  BARS  SECURITY  
*  LAPUTA             Infra  1     54 Mbit/s  91      ▂▄▆█  WPA2       
   000000000000-2G    Infra  11    54 Mbit/s  45      ▂▄__  WPA1 WPA2 
   WARPSTAR-000000    Infra  3     54 Mbit/s  42      ▂▄__  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 
```

## `-f` オプションでフィールド指定
`-f` オプションを使うと表示できる項目を選択できます。標準では私にとっては不要なものがあったり欲しい情報がなかったりしますので、以下のように指定してみます。 `-f` オプションも OS バージョンで指定できるものが違うみたいで、 Ubuntu12 では IN-USE,CHAN,BARS は指定できないようです。

```console:
$ nmcli -f IN-USE,SSID,BSSID,CHAN,SIGNAL,BARS,SECURITY dev wifi
```

結果は以下のような感じです（※ SSID,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 
```

## リアルタイムで表示してみる
`tput` を使えばカーソル位置の変更とかが簡単にできますので、以下のようなシェルスクリプトを組むことでリアルタイムに画面が更新されるようなものを作ることができます。以下の場合は 1 秒ごとに更新しています。

```bash:
#!/bin/sh

tput clear #画面クリア
while true; do
        date +'%F %T'
        nmcli dev wifi
        tput ed #画面末までクリア
        sleep 1
        tput cup 0 0 #カーソルを0,0に移動
done
```

カーソルがちらちらするのがうっとしい場合はカーソルを非表示にしちゃえばもうちょっと綺麗になります。

```bash
#!/bin/sh
e() {
        tput cnorm #カーソルを通常表示に戻す
        exit
}
trap e 2 #SIGINT(CTRL+C)

tput civis #カーソルを非表示
tput clear
while true; do
        date +'%F %T'
        nmcli dev wifi
        tput ed
        sleep 1
        tput cup 0 0
done
```

コマンドラインでできることのうれしいところは Linux の豊富なコマンドを使ってカスタマイズが簡単にできるところです。例えば `grep` コマンドで特定に BSSID のものを強調させたり、絞ったり、 `sed` で修正したりといった事ができます。

`grep` コマンドは条件にマッチしたものを抽出するのに使うコマンドですが、条件の最後に `|$` を追加すれば条件にマッチしたものを強調することだけに使えます。 `|$` は全ての行にマッチし、マッチしたとしても改行文字なので強調されないというわけです。

以下は WEP を使っている AP を強調表示する例です。 `grep -E` よりも `egrep` の方が慣れているのでそっちをつかっていますが、 `grep -E` でも結果は同じになると思います。

```bash
#!/bin/sh
tput clear
while true; do
        nmcli -f IN-USE,SSID,BSSID,SIGNAL,SECURITY dev wifi | \
        egrep --color=always '^.*WEP.*$|$'
        tput ed
        sleep 1
        tput cup 0 0
done
```

## （おまけ）grep の強調色を変更する
`grep` の強調表示の色は「赤の強調」なんですが、 GREP_COLOR 変数に値を指定することで変更することができます `grep` の行のところを以下のようにすれば「青（強調でない）」に変更する事ができます。ちなみに GREP_COLOR のデフォルトは "01;31" らしいです。

```bash:
GREP_COLOR="0;32" egrep --color=always '^\*.*$|$'
```

## （参考）GREP_COLOR に指定できる値
[ANSI Escape sequences](http://ascii-table.com/ansi-escape-sequences.php) によると以下のような値が指定できるようです。

```text:
Text attributes
0	All attributes off
1	Bold on
4	Underscore (on monochrome display adapter only)
5	Blink on
7	Reverse video on
8	Concealed on
 
Foreground colors
30	Black
31	Red
32	Green
33	Yellow
34	Blue
35	Magenta
36	Cyan
37	White
 
Background colors
40	Black
41	Red
42	Green
43	Yellow
44	Blue
45	Magenta
46	Cyan
47	White 
```