speedometerで使用中のNICすべてのトラフィックを表示するワンライナー

# 概要

UbuntuやCent OSなど各種Linuxにおいて、シェル上でグラフィカルにトラフィックを表示するコマンドとして、speedometerがある。

ただこのspeedometer、律儀に対象のNICを引数に指定してあげないといけない(オプション無しなら全部表示してくれてもいいのに)。
[Predictable Network Interface Names](https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/)のせいでマシンによってネットワークデバイス名が変わってくるので、いちいち調べないといけないのは面倒。

そこでアクティブなNICすべてを表示するためのワンライナー(にはちょっと長いかな？)を作った。

# 完成品

~~~bash
speedometer `ip link show up | grep -E "^[0-9]+: [^@]+?: <BROADCAST.*>" | cut -d" " -f2 | sed -e "s/\(.\+\)\:/-c -r \1 -t \1/g" | tr "\n" " " | cut -d" " -f2- `
~~~

見にくいので行分割バージョン

~~~bash
speedometer `ip link show up | grep -E "^[0-9]+: [^@]+?: <BROADCAST.*>" | cut -d" " -f2 | \
  sed -e "s/\(.\+\)\:/-c -r \1 -t \1/g" | tr "\n" " " | cut -d" " -f2- `
~~~

(追記)
物理NICに限る場合は下記

~~~bash
speedometer `ls -l /sys/class/net/ | grep -v virtual | cut -d" " -f9 | sed "/^$/d" | sed -e "s/\(.\+\)/-c -r \1 -t \1/g" | tr "\n" " " | cut -d " " -f2-`
~~~

## 実行結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/197772/f49ec74e-e102-fe7b-5b34-65c6ca5b08fd.png)

## 解説

まず`ip link show up`でSTATEがUPとなっているネットワークデバイスを列挙。

~~~
$ ip link show up
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 20:c6:eb:0f:cb:0f brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether e2:9d:fa:6a:25:15 brd ff:ff:ff:ff:ff:ff
5: ap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 44:85:00:72:28:4d brd ff:ff:ff:ff:ff:ff
11: veth6GY7BI@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether fe:69:6f:80:a3:70 brd ff:ff:ff:ff:ff:ff link-netnsid 0
~~~

ちなみにこの環境では、ブリッジインターフェースの`br0`に、物理Ethernetインターフェースの`enp0s31f6`と、hostapdで動かしている無線アクセスポイントの`ap0`がぶら下がっている。
無線LANのデバイス(ちなみに`wlp2s0`)はSTATEがDOWNになっているため表示されていない。
また、LXDのコンテナーが使うネットワークデバイスが`veth6GY7BI@if10`となっている。

次に、grepでデバイス名を含む行で、かつ@を含まない、`BROADCAST`を含む、という条件で、

* LXDコンテナが使うvethデバイス
* ループバックデバイス

を除去。

~~~
$ ip link show up | grep -E '^[0-9]+: [^@]+?: <BROADCAST.*>'
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP mode DEFAULT group default qlen 1000
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
5: ap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP mode DEFAULT group default qlen 1000
~~~

cutで空白区切りにした場合の2番目のフィールドを取り出す。

~~~
$ ip link show up | grep -E '^[0-9]+: [^@]+?: <BROADCAST.*>' | cut -d' ' -f2
enp0s31f6:
br0:
ap0:
~~~

speedometerの引数の形式になるようにsedで置換。
`-c`は新しく列を作る、`-r`は受信、`-t`は送信。

~~~
$ ip link show up | grep -E '^[0-9]+: [^@]+?: <BROADCAST.*>' | cut -d' ' -f2 | sed -e 's/\(.\+\)\:/-c -r \1 -t \1/g'
-c -r enp0s31f6 -t enp0s31f6
-c -r br0 -t br0
-c -r ap0 -t ap0
~~~

trで改行をスペースに置換。

~~~
$ ip link show up | grep -E '^[0-9]+: [^@]+?: <BROADCAST.*>' | cut -d' ' -f2 | sed -e 's/\(.\+\)\:/-c -r \1 -t \1/g' | tr '\n' ' '
-c -r enp0s31f6 -t enp0s31f6 -c -r br0 -t br0 -c -r ap0 -t ap0 
~~~

一番最初の`-c`は不要なので削除。

~~~
$ ip link show up | grep -E '^[0-9]+: [^@]+?: <BROADCAST.*>' | cut -d' ' -f2 | sed -e 's/\(.\+\)\:/-c -r \1 -t \1/g' | tr '\n' ' ' | cut -d' ' -f2-
-r enp0s31f6 -t enp0s31f6 -c -r br0 -t br0 -c -r ap0 -t ap0
~~~

これをspeedometerの引数に渡せば完成！
(先頭の`-c`を1つ削除するのに苦労した。またawkを使うとワンライナーをaliasに設定するときにエスケープが大変なので、sedとcutで頑張ってみた)