/etc/hostsに書いた設定が効いているか、ホスト名がどのIPアドレスに解決されるかを、アプリケーションが見る結果のまま確認したいときは、getent hostsを使う。

$ getent hosts myserver.test
10.0.0.5        myserver.test

/etc/hostsに10.0.0.5 myserver.testを書いた環境での実行例である。getent hostsは/etc/nsswitch.confのhostsの行に従い、/etc/hostsやDNSを順に引く。実行例はUbuntu 24.04(glibc 2.39)のもの。

macOSにはgetentが無い。Linux専用のコマンドである。

digやnslookupでは/etc/hostsの設定を確認できない

digとnslookupはDNSサーバーにだけ問い合わせる。/etc/hostsにだけ書いたホスト名は、見つからない。

$ nslookup myserver.test
Server:		192.168.5.2
Address:	192.168.5.2#53

** server can't find myserver.test: NXDOMAIN

$ dig +short myserver.test

dig +shortは何も表示しない。一方、getent hostsは/etc/hostsの内容を返す。curlやsshなど、glibcのリゾルバ(getaddrinfo)を使うアプリケーションは、getent hostsと同じ経路で名前解決する。アプリケーションが接続する先を調べるときは、digよりgetent hostsが確実である。

digの出力の読み方は次の記事を参照。

参考: 【dig】DNSの問い合わせ結果を読む

解決順はnsswitch.confで決まる

名前解決の順序は/etc/nsswitch.confのhostsの行で決まる。

$ grep ^hosts /etc/nsswitch.conf
hosts:          files dns

filesは/etc/hosts、dnsはDNSサーバーを表す。左から順に引き、見つかった時点で結果を返す。

/etc/hostsに実在するドメインの別のIPアドレスを書くと、getent hostsは/etc/hostsの値を返す。digはDNSの値を返す。

$ echo "10.9.9.9 example.com" | sudo tee -a /etc/hosts
$ getent hosts example.com
10.9.9.9        example.com
$ dig +short example.com A
172.66.147.243
104.20.23.154

hostsの行をdns filesに入れ替えると、DNSの結果が優先される。DNSに無いホスト名だけが/etc/hostsから引かれる。

$ sudo sed -i 's/^hosts:.*/hosts: dns files/' /etc/nsswitch.conf
$ getent hosts example.com
172.66.147.243  example.com
104.20.23.154   example.com
$ getent hosts myserver.test
10.0.0.5        myserver.test

特定の参照元だけで引きたいときは-sオプションを使う。

参考: 【getent】参照元を指定して取得する (-s)

IPアドレスからホスト名を調べる

引数にIPアドレスを渡すと、ホスト名を引ける。/etc/hostsにあるIPアドレスなら、対応するホスト名が返る。

$ getent hosts 10.0.0.5
10.0.0.5        myserver.test
$ getent hosts ::1
::1             localhost ip6-localhost ip6-loopback

複数のホスト名をまとめて調べる

引数には複数のホスト名を並べられる。ホスト名の順に結果が表示される。

$ getent hosts myserver.test localhost
10.0.0.5        myserver.test
::1             localhost ip6-localhost ip6-loopback

1つでも解決できないホスト名があると、終了コードは2になる。解決できたホスト名の結果は表示される。

$ getent hosts nonexist.invalid localhost
::1             localhost ip6-localhost ip6-loopback
$ echo $?
2

引数を省略すると、/etc/hostsのIPv4のエントリが表示される。IPv6のアドレスだけを持つ行は表示されない。

$ getent hosts
127.0.0.1       localhost
127.0.0.1       localhost ip6-localhost ip6-loopback
10.0.0.5        myserver.test
172.17.0.2      26dc65d005cb

参考: 【getent】データベースのエントリを全件列挙する (キー省略)

IPv4とIPv6の両方を持つ名前はIPv6が先に返る

同じ名前にIPv4とIPv6の両方のアドレスがある場合、getent hostsはIPv6のアドレスを優先して返す。/etc/hostsに両方を書いて確認できる。

$ printf '10.1.1.1 dual.test\nfd00::1 dual.test\n' | sudo tee -a /etc/hosts
$ getent hosts dual.test
fd00::1         dual.test

localhostが127.0.0.1ではなく::1で返るのも、同じ理由である。IPv4のアドレスだけが欲しいときや、全アドレスを一覧したいときは、getent ahosts系のデータベースを使う。

参考: 【getent】IPv4とIPv6の全アドレスを一覧表示する (ahosts)

シェルスクリプトからIPアドレスだけを取り出す

出力は1列目がIPアドレスである。cutやawkで取り出せる。

$ getent hosts example.com | cut -d' ' -f1 | head -n1
172.66.147.243
$ getent hosts example.com | awk '{print $1; exit}'
172.66.147.243

nslookupやdigが無い環境でIPアドレスを調べる方法は、次の記事でも扱っている。

参考: 【getent hosts】 nslookupやdigコマンドが無いLinux環境でIPアドレスを調べる