Nie jest to możliwe, ponieważ format jest zwykle głęboko zakodowany w libc platform. Jednak jest to sobie wyobrazić, że OS dodaje tej funkcji, co czyni go non rozwiązanie cross-platform.
Alternatywnie możesz automatycznie zaktualizować określony blok w pliku hosts. Jest to szczególnie przydatne, jeśli masz skrypt, który dynamicznie wyświetla wpisy hosta dla określonego projektu (prawdopodobnie ze zmieniającymi się adresami IP).
Oto przykład: chcesz utworzyć hosty ze stanu Terraform za pośrednictwem terraform-inventory
.
Odpowiednie wyniki inwentaryzacji (na przykład mapowanie znacznika EC2 „Nazwa” na grupy dokładnie jednego hosta):
$ 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")'
Wyjście skryptu:
./print-updated-hosts-entries.sh
10.101.118.131 myhost-a
10.101.111.189 myhost-b
I wiersz polecenia, aby zaktualizować zaznaczony blok w /etc/hosts
wyniku działania skryptu :
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
Wyjaśnienie:
- Pierwsza linia oczywiście tworzy kopię zapasową
- Podpowłoka w nawiasach zawiera dwa
sed
wywołania, aby wydrukować wszystkie linie odpowiednio przed i po początku / końcu znacznika. W każdym przypadku wstawiamy znaczniki, umieszczając wynik skryptu między tymi wierszami. Nawet jeśli skrypt nie powiedzie się, nadal musimy otoczyć zawartość /etc/hosts
(i kopię zapasową w katastrofalnym scenariuszu).
sudo tee /etc/hosts.new
zapisuje potokową zawartość w nowym pliku
sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p'
drukuje zaktualizowany blok dla wygody
sudo mv /etc/hosts.new /etc/hosts
przenosi nowy plik na miejsce. Należy to zrobić w osobnym kroku, ponieważ jeśli w buforze potoku zabraknie miejsca, tee /etc/hosts
zacznie się zapisywać plik, gdy istniejąca zawartość jest nadal odczytywana.