LoginSignup
13
10

More than 5 years have passed since last update.

シェルにおける eth0 や en0 の IP アドレスの取得のしかたと、GNU sed と BSD sed の挙動違い

Last updated at Posted at 2015-01-30

Linux の場合。以下は Boot2docker の /etc/init.d/docker より。ip(8) と sed(1) を使っている。

$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether d8:50:e6:4c:be:de brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.64/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::da50:e6ff:fe4c:bede/64 scope link
       valid_lft forever preferred_lft forever
$ ip addr show eth0 | sed -nEe 's/^[ \t]*inet[ \t]*([0-9.]+)\/.*$/\1/p'
10.0.0.64

OS X には ip(8) が無いので ifconfig(8) を使う。そもそもで eth0 も無いが。そして驚いたことに、BSD sed は GNU sed と違い、タブを展開しない。

エスケープではなく、直接にタブ文字を入れろ、ということのようだ。 ∥ regex - How can I insert a tab character with sed on OS X? - Stack Overflow

以下は、Bash にタブを展開してもらった例。しかし、今度は \1 をエスケープする必要が生じた。

$ ifconfig en0 | sed -nEe $'s/^[ \t]+inet[ \t]+([0-9.]+).*$/\\1/p'
192.168.34.65

タブ文字を使いたくなければ、やはり sed(1) の方で、ブラケット展開の文字クラスを使って書かざるを得まい。ところがさらに、re_format(7) (BSD) に書かれていることと違って、[[:space:]]\s が等価でない問題が。

$ ifconfig en0 | sed -nEe 's/^[[:space:]]+inet[[:space:]]+([0-9.]+).*$/\1/p'
192.168.34.65
$ ifconfig en0 | sed -nEe 's/^\s+inet\s+([0-9.]+).*$/\1/p'
$ 

細かいところ、BSD は緩いのかね? Linux, OS X 両対応するなら以下で。 ∥ shell - Check if a program exists from a bash script - Stack Overflow

command -v ip &> /dev/null && \
 ip addr show eth0 | sed -nEe 's/^\s+inet\W+([0-9.]+).*$/\1/p' || \
 ifconfig en0 | sed -nEe 's/^[[:space:]]+inet[[:space:]]+([0-9.]+).*$/\1/p'

あるいは、こんなか。

(command -v ip &> /dev/null && ip addr show eth0 || ifconfig en0) | \
 sed -nEe 's/^[[:space:]]+inet[^[:alnum:]]+([0-9.]+).*$/\1/p'

追記(Feb 24 2015): eth0 や en0 の MAC アドレスが欲しい場合には、以下のような感じか。

(command -v ip &> /dev/null && ip addr show eth0 || ifconfig en0) | \
 sed -nEe 's/^[[:space:]]+(link\/)?ether[[:space:]]+([0-9a-f:]+).*$/\2/p'

追記(Apr 26 2016): Ubuntu のバージョンを上げて systemd になったせいか、NIC の命名ルールが PredictableNetworkInterfaceNames に変更になった。うちの子たちは 1 Ethernet しか積んでいないので、とりあえず一つ目に見つかった Ethernet デバイスの IP アドレスを取ってくるようにするよ。なお、DELL のハードウェアは Linux 的には特別扱いで、“biosdevname” なる、これまた別のルールで命名されるらしい。 ∥ RHEL7のNICのネーミングルール - めもめも

(command -v ip &> /dev/null && ip addr show \
 $(basename $(ls -d /sys/class/net/{en*,eth*,em*} 2> /dev/null | \
 head -n 1)) || ifconfig en0) | \
 sed -nEe 's/^[[:space:]]+inet[^[:alnum:]]+([0-9.]+).*$/\1/p'
13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10