フォーマットは通常、プラットフォームのlibcに深くコーディングされているため、不可能です。ただし、OSがこの機能を追加し、クロスプラットフォーム以外のソリューションにすることは想像できます。
または、hostsファイルの特定のブロックを自動的に更新できます。これは、特定のプロジェクトなどのホストエントリを動的に出力するスクリプトがある場合(IPを変更した場合など)に特に役立ちます。
次に例を示しますterraform-inventory
。を介してTerraform状態からホストを作成します。
関連するインベントリ出力(たとえば、EC2 "Name"タグをそれぞれ1つのホストのグループにマッピングする):
$ 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")'
スクリプト出力:
./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
、マーカー開始/終了の前後のすべての行をそれぞれ印刷する2つの呼び出しがあります。いずれの場合もマーカーを挿入し、スクリプト出力をそれらの行の間に入れます。スクリプトが失敗しても、周囲のコンテンツ/etc/hosts
(および壊滅的なシナリオでのバックアップ)が必要です。
sudo tee /etc/hosts.new
パイプされたコンテンツを新しいファイルに書き込みます
sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p'
便宜上、更新されたブロックを出力します
sudo mv /etc/hosts.new /etc/hosts
新しいファイルを所定の場所に移動します。パイプバッファの領域が不足するとtee /etc/hosts
、既存のコンテンツの読み取り中にファイルの書き込みが開始されるため、これは別の手順で行う必要があります。