It's not possible, as the format is usually deeply coded into platforms' libc. However it is imaginable that an OS adds this feature, making it a non cross-platform solution.
Alternatively, you can automatically update a certain block in your hosts file. This is particularly helpful if you have a script that dynamically outputs host entries for a certain project or so (possibly with changing IPs).
Here's an example: you want to create hosts from Terraform state via terraform-inventory
.
Relevant inventory output (for instance, mapping an EC2 "Name" tag to groups of exactly one host each):
$ terraform-inventory --list | jq 'with_entries(select(.key | match("^name_")))'
{
"name_myhost-a": [
"10.101.118.131"
],
"name_myhost-b": [
"10.101.111.189"
]
}
print-updated-hosts-entries.sh
#!/bin/sh
exec terraform-inventory --list | \
jq -r 'to_entries |
map(select(.key | match("^name_"))) |
map(.value[0] + " " + .key[5:]) |
join("\n")'
Script output:
./print-updated-hosts-entries.sh
10.101.118.131 myhost-a
10.101.111.189 myhost-b
And the command line to update a marked block in /etc/hosts
with the script output:
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
Explanation:
- The first line obviously creates a backup
- The subshell in parentheses has two
sed
calls to print all lines before and after the marker begin/end, respectively. We insert the markers in any case, putting the script output in between those lines. Even if the script fails, we still have to surrounding content of /etc/hosts
(and the backup in a catastrophic scenario).
sudo tee /etc/hosts.new
writes the piped content into a new file
sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p'
prints the updated block for convenience
sudo mv /etc/hosts.new /etc/hosts
moves the new file into place. This must be done in a separate step because if the pipe buffer runs out of space, tee /etc/hosts
would start writing the file while the existing content is still being read.
LC_COLLATE
), so the caveat in your answer does not apply. – l0b0 Mar 20 '18 at 23:56