hosts
is a command-line tool to build a hosts (/etc/hosts) file from multiple
sources.
The project's Janet source code compiles to a
stand-alone hosts
executable on all major platforms (GNU/Linux, Mac OS X,
BSD, Windows).
The hosts
binary is a standalone executable. Download a suitable binary from
project releases, or review Development to build
the executable locally. Simply add the executable to the system/shell PATH
.
A hosts file itself is simple: provide static data on how to resolve a given
hostname and its aliases to an IP address. The process of updating an IP
address or hostname can be a straightforward find/replace with Unix tools such
as sed
. A more generalized edit, however, gets complicated fast, because
hosts (/etc/hosts) data is relational. An IP address maps to one or more hosts
by name.
In order to allow for sophisticated updates, especially configuration updates
which assume nothing other than a valid hosts files, the hosts
command
provides for full parsing, merging, and in-place rewriting of hosts data.
Use cases:
- Create an unpublished alias for an existing host, by running a script as a
scheduled task (i.e. cron) to perform a DNS query and update /etc/hosts with
hosts -f /etc/hosts -s "<ip> <domain>"
. This is particularly useful for not-yet-published domains which are under development, and for moving aliases from program-local configurations like~/.ssh/config
to system-wide aliases available to all programs. - Coordinate hosts with DNS discovery without a name server, by distributing a
hosts file which then overlays the existing /etc/hosts file with
hosts -f /etc/hosts -f <file>
. This provides a minimalist approach to service discovery and orchestration, especially when configuration management tools are already in place. - Merge multiple hosts files on a network appliance.
(Redirect hosts
stdout output to perform the actual update of /etc/hosts.)
Help output available with hosts -h
:
usage: hosts [option] ...
Build a hosts (/etc/hosts) file from multiple sources.
Optional:
-d, --delimiter VALUE=' ' Whitespace to append hostname.
-f, --file VALUE A hosts file as input.
-h, --help Show this help message.
-s, --static VALUE A static hosts entry.
-v, --version Output version, then exit.
Example command to write the IPv4 address of example.net
as server
:
hosts -f /etc/hosts -s "$(dig example.net A +short | grep '^[.0-9]*$') server"
Redirect stdout to write to a file. Example:
hosts -f /etc/hosts.base -s "192.168.1.10 example.com # comment" > /etc/hosts
hosts
accepts repeated command-line flags for arbitrarily many input files.
A hosts file contains lines with the pattern:
<ip> <hostname> [<alias>]... # comment
Fields delimit with whitespace comprised of any number of spaces and/or
tabs. Comments start with a hash (#
) and blank lines are allowed. Hostnames
can have alphanumeric characters and hyphens (-
); they can be up to 63
characters, must begin with an alphabetic character, and must not end in a
hyphen. Domain names combine hostname elements with a dot (.
) and must not be
longer than 253 characters. Hostnames are case-insensitive and can have zero or
more aliases.
As hosts
processes input hosts lines, it will:
- Preserve order. Read input line by line, left to right in the command-line arguments. Any line matching a previous line, either by IP or hostname alias, will update the fields of the previous line instead of writing to output.
- Discard redundant comments. Any line matching a previous line will have its comment (if any) discarded, such that the first-seen matching hosts line will be the only to have its comment in the output.
- Use latest information. The last line in a group of matched lines is presumed to have the latest information on the IP for all aliases in the match; the output includes that IP for all matched aliases.
A hosts file can specify both IPv4 and IPv6 addresses for a hostname. In
effect, IPv4 and IPv6 are separate and distinct namespaces within the hosts
file. When matching IP addresses, hosts
tracks IPv4 and IPv6 addresses
separately.
While hosts
can reliably rewrite hosts data in-place, repeat autonomous calls
to hosts
benefit from writing to an output file which is not ultimately used
as an input file in a later invocation. This will avoid the case where a
previously merged alias is now out-of-date and unused. Aliases merge, but
nowhere in the process are they dropped without manual edits.
References:
man 7 hostname
on Linuxman 5 hosts
on Linux
This project provides a single-command build to install a project-local Janet,
install dependencies, build, and test. On a Unix-like system, just run GNU Make
(make
, which is sometimes gmake
on BSD systems):
make
On Windows:
.\bin\build.cmd
Otherwise, with Janet installed, build and test:
[sudo] jpm deps # first time only
jpm test
The build/
directory contains the jpm build
(called by jpm test
) output
of a redistributable binary for the current platform.
Copyright (c) 2019-2021, R. DuPlain. All rights reserved. BSD 2-Clause License.