这是不可能的,因为该格式通常被深度编码到平台的libc中。然而,它是可以想象的OS还添加了这项功能,使之成为非跨平台解决方案。
或者,您可以自动更新主机文件中的特定块。如果您有一个脚本可以动态输出某个项目左右的主机条目(可能会更改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
说明:
- 第一行显然会创建一个备份
- 括号中的子外壳有两个
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
则会在仍在读取现有内容的同时开始写入文件。