Perl でローカルのアドレスを取得する
まだ Linux を触り始めて間もない頃に、サーバーを構築していてローカルの IP アドレスをシェルスクリプトから利用する必要があって、どうやって取得するべきだろうかと小一時間悩んだのですが結局分からず Perl の正規表現で ifconfig を parse したことがありました。ioctl() を使ってデバイスを操作する必要がある、ということを知ったのは数年後、割と最近のことです。なんということでしょう。
では、Perl で IP アドレスを取得する場合ですがモジュールを使ってよいのであれば IO::Interface がよいだろうと思っています。IO::Interface は Pure Perl ではありませんが、XS で ioctl() を呼び出しているので比較的高速且つ素直な実装だと思います。
#!/usr/local/bin/perl use strict; use warnings; use IO::Handle; use IO::Interface::Simple; STDOUT->printf("%s\n", IO::Interface::Simple->new(shift || 'eth0')->address);
で
% perl ip_address.pl eth0 192.168.100.2
と出ます。
このモジュールはほぼ「ioctl() によるネットワークインタフェース操作のラッパ」という位置づけですので、ハードウェアアドレスそのほかの情報も取得できます。作者は CGI.pm や Perlネットワークプログラミング―ソケットの使い方からクライアント/サーバーシステムの開発まで でおなじみの Lincoln D. Stein 氏です。
他にも CPAN には Net::Addresss::Ethernet などがありますが、こちらは Net::Ifconfig::Wrapper を使って ifconfig の出力を parse しています。OS ごとの出力の違いなどを吸収するために結構泥臭いコードになっているようです。XS でも問題ない環境であれば IO::Interface のほうが良いでしょう。
PerlやEmacsのようななんでもできるツールは勝って当然、sedで勝つところが醍醐味です。例えて言えば、激ペナでボールになる変化球ばかり使って打ち取るのがPerlやEmacsで、ストレート一本、ストライク勝負で打ち取るのがsedの世界です。
激突ペナントレースは小学生の頃にやって以来なのでほぼ記憶の彼方ですが、ここでは有無を言わさずスライダー、のような方法を紹介してみました。
追記
Linux なら sysfs で /sys/class/net/eth0 からも取れる、とコメントをいただきました。知らなかった! sysfs 経由では IP アドレスは取れない?