如何让该/etc/hosts
文件引用另一个配置文件来获取其主机列表?
例子/etc/hosts
:
## My Hosts
127.0.0.1 localhost
255.255.255.255 broadcasthost
#Other Configurations
<Link to /myPath/to/MyConfig/ConfigFile.txt>
#Other Addresses
3.3.3.3 MyAwesomeDomain.com
4.4.4.4 SomeplaceIWantToGoTo.com
配置文件.txt
##My additional Hosts
1.1.1.1 SomeLocation.com
2.2.2.2 AnotherLocation.com
如何添加/etc/hosts
文件的链接/引用以便加载 ConfigFile.txt?
答案1
你不能。的格式/etc/hosts
非常简单,并且不支持包含额外的文件。
您可以使用以下几种方法:
设置(可能仅限本地)DNS 服务器。其中一些给出了很多灵活性,您绝对可以将主机文件分布在多个文件甚至机器上。其他(例如 dnsmasq)提供的灵活性较少(但仍然足够),但易于设置。如果您尝试在一堆计算机上包含相同的主机列表,那么 DNS 可能是正确的答案。
设置一些其他名称服务(NIS、LDAP 等)。检查 glibc NSS 文档以了解支持的内容。就我个人而言,我认为在大多数情况下都应该使用 DNS。
为自己创建一个
/etc/hosts.d
目录或类似目录,并编写一些脚本将它们连接在一起(最简单:cat /etc/hosts.d/*.conf > /etc/hosts
尽管您可能希望更好一点,例如按当前区域设置覆盖默认排序),然后在启动时运行该脚本,或者从 cron 执行,或者在更新文件时手动执行。
就个人而言,无论是在家里还是在工作中,为了让每台设备都能解析机器名称,我运行 BIND 9。不过,这确实需要几个小时的学习时间。
答案2
这是不可能的,因为该格式通常被深度编码到平台的 libc 中。然而它是可以想象,操作系统添加了此功能,使其成为非跨平台解决方案。
或者,您可以自动更新主机文件中的某个块。如果您有一个脚本可以动态输出某个项目的主机条目(可能会更改 IP),那么这会特别有用。
这是一个示例:您想通过以下方式从 Terraform 状态创建主机terraform-inventory
。
相关清单输出(例如,将 EC2“名称”标签映射到每个仅包含一台主机的组):
$ terraform-inventory --list | jq 'with_entries(select(.key | match("^name_")))'
{
"name_myhost-a": [
"10.101.118.131"
],
"name_myhost-b": [
"10.101.111.189"
]
}
打印更新的主机条目.sh
#!/bin/sh
exec terraform-inventory --list | \
jq -r 'to_entries |
map(select(.key | match("^name_"))) |
map(.value[0] + " " + .key[5:]) |
join("\n")'
脚本输出:
./print-updated-hosts-entries.sh
10.101.118.131 myhost-a
10.101.111.189 myhost-b
还有/etc/hosts
使用脚本输出更新标记块的命令行:
sudo cp /etc/hosts "/etc/hosts.bak.$(date +%Y%m%d%H%M%S)" && \
(
sed -n '1,/^# MYMARKER BEGIN/{/^# MYMARKER BEGIN/!p;}' /etc/hosts; \
echo "# MYMARKER BEGIN"; \
./print-updated-hosts-entries.sh; \
echo "# MYMARKER END"; \
sed -n '/^# MYMARKER END/,${/^# MYMARKER END/!p;}' /etc/hosts; \
) | \
sudo tee /etc/hosts.new | \
sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p' && \
sudo mv /etc/hosts.new /etc/hosts
解释:
- 第一行显然创建了一个备份
- 括号中的子 shell 有两个
sed
调用,分别打印标记开始/结束之前和之后的所有行。无论如何,我们都会插入标记,将脚本输出放在这些行之间。即使脚本失败,我们仍然必须围绕内容/etc/hosts
(以及灾难性情况下的备份)。 sudo tee /etc/hosts.new
将管道内容写入新文件sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p'
为了方便起见打印更新的块sudo mv /etc/hosts.new /etc/hosts
将新文件移动到位。这必须在单独的步骤中完成,因为如果管道缓冲区空间不足,tee /etc/hosts
则会在仍在读取现有内容的同时开始写入文件。
答案3
我也有类似的要求,需要使用动态 IP 在不同位置无缝工作,特别是因为我使用虚拟机。我对此的简单解决方案如下:
创建一个脚本来更新每个实体的主机条目。例如,如果我有一个名为“myhost.net”的主机,带有子域“app.myhost.net”,我将调用该脚本并提供一个 IP 地址,该地址将为每个域写入并保存在名为的主机文件中“我的主人”。同一脚本有一个用于删除或更新单个主机文件的标志。
创建另一个脚本将这些文件合并到 /etc/hosts 中。该脚本将找到您创建的所有主机文件,并将它们合并到 /etc/hosts 中的单个主机文件中。
这对我来说非常有效。我远程工作,有时出于任何原因需要在不同地点之间移动,并且会因多次编辑一个文件的需求而感到负担。相反,我只运行一个脚本。是的,一个脚本。第一个脚本自动运行另一个脚本以自动进行合并。
答案4
有一些更简单的提示:
创建名为“个人主机”的文件
将所有自定义主机存储在该文件上。
然后将文本文件附加到“hosts”
cat personal-hosts >> hosts
这个简单的技巧帮助我在拥有超过 120k 主机列表的超大型主机上添加畅通无阻的添加服务器