読者です 読者をやめる 読者になる 読者になる

ARMERIA

通信とWeb技術とRubyとゲーム制作と

インタフェースのMACアドレス「だけ」を取ってくる方法はないものか

通信系のエントリを書くのは初めてかも?

Linuxの場合、インタフェースのMACアドレスとかIPアドレスとかは、ipコマンドで表示することができます。(実行環境はVirtualBox上のCentOS 6です)

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:3d:94:80 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fe3d:9480/64 scope link
       valid_lft forever preferred_lft forever

ただ単にipコマンドを使うだけだと、上記のように色んな情報がずらずらーっと出てきます。

目視で確認するだけなら上の方法で構わないんですが、スクリプトで処理を自動化する時などは、1つのインターフェースの1つの情報だけを取ってきたい、ということがたまにあります。

ipコマンドのオプションとか、別のコマンドでできないかな?と思って色々調べましたが、どうやらなさそうなので、泥臭いですがシェルスクリプトで文字列操作して取り出す、という方法を考えました。

まずip addr show eth0などとすると、表示対象を1つのインタフェースに限定することができます。

$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:3d:94:80 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fe3d:9480/64 scope link
       valid_lft forever preferred_lft forever

MACアドレスを取ってきたい場合、目当ての値はlink/etherの直後にあるので、まずlink/etherが含まれる行だけを取ってきます。

$ ip addr show eth0 | grep link/ether
    link/ether 08:00:27:3d:94:80 brd ff:ff:ff:ff:ff:ff

最後にsedMACアドレスだけを持ってきます。表示の形式に合わせて正規表現を組みます。

$ ip addr show eth0 | grep link/ether | sed -E "s@.*link/ether\s(\S+)(\s.*|$)@\1@g"
08:00:27:3d:94:80

sedの式は、ラベル(ここではlink/ether)とスペースに続く値を取り出します(\S+の部分が本命の取って来たい値)。/ipの出力内容によく含まれているので、区切り記号は登場しなさそうなものに変更。

同じようにIPv4アドレスは以下のような感じ。サフィックスは除去するようにしてみました。grep時に単にinetとするとinet6にもマッチしてしまうので注意。

$ ip addr show eth0 | grep "inet\s" | sed -E "s@.*inet\s(\S+)/[0-9]+(\s.*|$)@\1@g"
10.0.2.15

当然この方法はipコマンドの出力形式に依存するので、バージョンが変わった時の動作保証はできません…あとは表示内容次第で思わぬ正規表現のマッチが起こってしまうかも。何かスマートな方法はないものか。