/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の出力の読み方は次の記事を参照。
解決順は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オプションを使う。
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アドレスを調べる
