Personal tools
You are here: Home ブログ 井上 ifconfigの出力をsedでパース
« February 2010 »
Su Mo Tu We Th Fr Sa
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28            
Recent entries
「DHTからAmazon Dynamoまで」プレゼン資料を公開します inoue 2010-02-07
演算子の記法 inoue 2010-02-03
mod_proxy_balancerを使う時のProxyPassReverseの設定 inoue 2010-02-02
プログラマの指標 inoue 2010-02-02
IPA未踏ユース採択結果 inoue 2010-01-26
synergy にある典型的なバグ(とパッチ) inoue 2010-01-24
「パーフェクトJava」の「国際化」の章の原稿を公開 inoue 2010-01-22
「P2P教科書」を読む inoue 2010-01-15
tcpstat: netstatより細かくネットワーク統計量を見るツール inoue 2010-01-11
Apacheバージョン1系はそろそろ保守終了の様子 inoue 2010-01-06
Oracleのインデックスのツリーのバランスが崩れる? inoue 2009-12-27
HTTPのリダイレクトとPOSTメソッドの話 inoue 2009-12-26
Recent comments
Re:「DHTからAmazon Dynamoまで」プレゼン資料を公開します inoue 2010-02-08
Re:演算子の記法 Anonymous Coward 2010-02-03
Re:「パーフェクトJava」の「国際化」の章の原稿を公開 inoue 2010-01-30
Re:「パーフェクトJava」の「国際化」の章の原稿を公開 Anonymous User 2010-01-29
Re:synergy にある典型的なバグ(とパッチ) inoue 2010-01-28
Re:「パーフェクトJava」の「国際化」の章の原稿を公開 inoue 2010-01-20
Re:「パーフェクトJava」の「国際化」の章の原稿を公開 Anonymous User 2010-01-19
Re:tcpstat: netstatより細かくネットワーク統計量を見るツール Anonymous User 2010-01-15
Re:ソフトウェアのマニュアル管理に適したツール? fchiba 2010-01-08
Re:ソフトウェアのマニュアル管理に適したツール? inoue 2010-01-07
Re:ソフトウェアのマニュアル管理に適したツール? fchiba 2010-01-07
Re:Apacheバージョン1系はそろそろ保守終了の様子 おおたに 2010-01-07
Categories
カテゴリなし
 
Document Actions

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の世界です。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/we-love-sed/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.