![读取 /etc/hosts 的程序/应用程序或脚本](https://linux22.com/image/142966/%E8%AF%BB%E5%8F%96%20%2Fetc%2Fhosts%20%E7%9A%84%E7%A8%8B%E5%BA%8F%2F%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%88%96%E8%84%9A%E6%9C%AC.png)
当需要名称解析时,打开并读取 /etc/hosts 的程序或脚本的名称是什么?每个 linux/unix 发行版都有不同吗?
我阅读了主机的手册页,并尝试在 whereis 中查找名为主机的二进制文件,但 whereis 输出文件名,例如 /etc/hosts.allow 和 /etc/hosts.deny。我的印象是hosts.allow 和hosts.deny 是TCPWrappers 的配置文件,现在我比开始时更加困惑。
答案1
没有具体的程序解析这个文件。
许多标准文件(例如/etc/hosts
)由标准库文件(例如)解析gethostbyname(3)
。然而,故事可能要复杂得多。
主机名解析通常由 中的条目控制/etc/nsswitch.conf
。
例如
% grep hosts /etc/nsswitch.conf
hosts: files dns
此条目告诉解析器例程使用“文件”后端,如果在那里找不到结果,则进行 DNS 查找。可以在那里放置其他值(例如ldap
或nis
),这可以更改主机名的查找方式。
这些例程通常称为“命名服务”。相同的概念也用于用户名查找 ( passwd
)、组条目 ( group
) 等。
因此,当您这样做ping a.remote.host
时,ping
程序将调用 glibc 库函数,这将加载nsswitch.conf
.结果是您不会看到执行查找的特定程序;ping
通过库和 NS 例程自行完成工作。
有一个名为 的程序getent
可以用来进行姓名搜索;您指定一个“数据库”(中的条目之一nsswitch.conf
)和要搜索的值。
所以
getent hosts a.remote.host
将按照 中定义的规则进行名称查找nsswitch.conf
。这对于测试目的很有用,有时在脚本中也很有用。
--- 附录 ----
此信息来自下面斯蒂芬的评论,但非常有用,因此我将其添加到他的答案中。
strace getent hosts www.google.com 2>&1 | grep libnss_
将告诉哪个库(或没有)用于解析名称。如果它说libnss_files
,那么就/etc/hosts
被使用了。如果显示libnss_dns
,则使用了 DNS。libnss_myhostname
意味着什么都不起作用,并且备份 GNU 系统踢了它(并且可能已经失败)。如果没有列出库,那么您可能使用了数字地址,例如127.0.0.1
,因此不需要解析器。
答案2
在 GNU/Linux 系统上,/etc/hosts
通常由库读取glibc
。
看GNU 的文档就此主题而言:
在内部,系统使用数据库来跟踪主机名和主机号之间的映射。该数据库通常是文件 /etc/hosts 或名称服务器提供的等效文件。用于访问该数据库的函数和其他符号在 netdb.h 中声明。它们是 BSD 功能,如果包含 netdb.h,则无条件定义。
所有 POSIX 兼容的 UNIX 和类 UNIX 系统都将遵循此准则,因为 netdb.h 是POSIX标准。主要区别在于它们使用的 C 库,因为并非所有 UNIX 系统都使用glibc
.
GNU 文档还讨论了诸如 和gethostbyname
之类的函数gethostbyaddr
,这些函数读取从 收集的数据/etc/hosts
。这两个函数今天实际上已经过时了。getaddrinfo
和getnameinfo
应该使用。