ifconfigの出力をsedでパース
GNU/LinuxでローカルのIPアドレス、ブロードキャストアドレス、ネットマスクを取得するコード例は以下のようになります。
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> #include <arpa/inet.h> /* for inet_ntoa() */ int main(int argc, char **argv) { struct ifreq ifr; const char *ifname = "eth0"; int sock = socket(AF_INET, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, ifname); ifr.ifr_addr.sa_family = AF_INET; if (ioctl(sock, SIOCGIFADDR, &ifr) == 0) { struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr; printf("%s\n", inet_ntoa(sin->sin_addr)); } if (ioctl(sock, SIOCGIFBRDADDR, &ifr) == 0) { struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_broadaddr; printf("%s\n", inet_ntoa(sin->sin_addr)); } if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) { struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_netmask; printf("%s\n", inet_ntoa(sin->sin_addr)); } close(sock); return 0; }
コード例を見てわかるように"eth0"というネットワークインターフェース名に依存したコードになっています。 ifconfigコマンドは、/proc/net/devファイルを開いてインターフェース名を取得しています。
AirOneでローカルIPアドレスを取得する必要があります。上のようなコードを書くのが面倒なので、ifconfig(1)の出力をパースしています。次のようなシェルスクリプトです。
LANG=C /sbin/ifconfig -a | sed -n '/.*inet addr:\([0-9.]*\).*Mask:\([0-9.]*\)/{s//\1 \2/;p;q}'
これは少し問題がありました。lo(loopback)インターフェースが先に現れると、そのアドレスを拾ってしまいます。loインターフェースは読み飛ばす必要があります。grepを挟むか、あるいはsedをperlで書き換えるかと迷いましたが、次のように簡単にsedで書けました。perl使ったら負けだと思っていました。
LANG=C /sbin/ifconfig -a | sed -n '/^lo/,/^$/d; /.*inet addr:\([0-9.]*\).*Mask:\([0-9.]*\)/{s//\1 \2/;p;q}'
動作を簡単に説明します。-nオプションで暗黙の出力を抑制しています。この例のようにマッチしたパターンだけを表示したい場合には有効なオプションです。/^lo/,/^$/d でひとかたまりです。dの部分がコマンドです。カッコをつけて /^lo/,/^$/{d} と書くこともできます。// の中はそれぞれ正規表現です。loで始まる行と空行です。カンマでつなぐと、それぞれの正規表現にマッチする間コマンドを実行、という意味になります。dコマンドはパターンスペース(入力行)を削除して、次の行を読み込みます。-nオプションを指定している場合、単に入力行を無視して次の行を読む、と見なして構いません。後続する部分は // で囲まれた正規表現がマッチ条件で、{}で囲まれた部分がコマンドです。sは置換、pは出力、qは終了です。実に直感的な命名です。
PerlやEmacsのようななんでもできるツールは勝って当然、sedで勝つところが醍醐味です。例えて言えば、激ペナでボールになる変化球ばかり使って打ち取るのがPerlやEmacsで、ストレート一本、ストライク勝負で打ち取るのがsedの世界です。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/we-love-sed/tbping