A while ago I wrote up a method for switching between
/etc/hosts files. That post is pretty popular and clearly been useful to a few people.
Since then I’ve actually extended this method into a tool that can manage multiple
/etc/hosts files. Using this new method you can have a folder that you can add hosts configurations to, and those files become available for switching into
/etc/hosts straight away.
There’s no reason why an adaptation of this method wouldn’t work in Linux as well.
Here’s how you do it:
1. Create the host configuration directory
We’ll store all the
/etc/hosts type files in
You’ll need to do all of this as a root user. So switch to root using
sudo -s first (you’ll need to be an administrator to do this).
$ mkdir -p /usr/local/share/hs
$ chmod 755 /usr/local/share/hs
Now to start with, let’s make a copy of the existing
/etc/hosts file in this directory.
$ cp /etc/hosts /usr/local/share/hs/hosts.normal
$ chmod 744 /usr/local/share/hs/hosts.normal
Then make the real
/etc/hosts a symbolic link to that new file.
$ ln -sf /usr/local/share/hs/hosts.normal /etc/hosts
Any additional host configurations in this folder need to be named using a similar
2. Create the host switching script
Take the following bash script and save it to a file located at
if [ $1 ]; then
# Change this if you put your host files elsewhere
echo "Attempting to switch host file to $HPATH$HFILE"
if [ ! -e $HPATH$HFILE ]; then
echo "--> File does not exist!"
echo "--> Exiting with status 1"
if [ -d $HPATH$HFILE ]; then
echo "--> File is a directory!"
echo "--> Exiting with status 2"
if [ -h $HPATH$HFILE ]; then
echo "--> File is a symbolic link!"
echo "--> Exiting with status 3"
if [ ! -h /etc/hosts ]; then
echo "--> Current hosts file is a real file!"
echo "--> Exiting with status 4"
# Link it up
sudo ln -sf $HPATH$HFILE /etc/hosts
# Flush the system-wide DNS cache
if [ -x /usr/bin/dscacheutil ]; then
# Mac OS X 10.5
elif [ -x /usr/bin/lookupd ]; then
# Mac OS X Less than 10.5
elif [ -x /usr/sbin/lookupd ]; then
# Mac OS X Less than 10.5 (alternative)
echo "--> Done"
The script does some basic validity checking on the file and also makes sure that
/etc/hosts is just a symbolic link and not a real file.
You will need to adjust the permissions on this script so that only admins can run it.
$ chmod 750 /usr/local/bin/hs
You also need to make sure that
/usr/local/bin is in your PATH so that the
hs command can be found. We can test that.
$ echo $PATH
… will output something like …
If it’s not there then you need to add it in your users
~/.profile file. Add the following line to that file, you can create the file if it isn’t there.
Now reload your profile and the
hs command should be available.
$ . ~/.profile
You could also just close and open your terminal window to reload your profile.
3. Trying it out
hs command takes one argument. The argument is used to specify the hosts configuration file to be loaded from
/usr/local/share/hs. If no argument is given, then the assumed file is
So for our first test we should add another hosts configuration.
$ cp /usr/local/share/hs/hosts.normal /usr/local/share/hs/hosts.test
Edit the new hosts configuration file to your liking.
Now we can try the switching command to switch to that configuration. You will need to supply your password if you are not already running as root.
$ hs test
Attempting to switch host file to /usr/local/share/hs/hosts.test
The symbolic link at
/etc/hosts should now be pointing to
$ ls -l /etc/hosts
/etc/hosts -> /usr/local/share/hs/hosts.test
Now try switching back to your normal configuration.
Attempting to switch host file to /usr/local/share/hs/hosts.normal
Any more configurations that you add to
/usr/local/share/hs are available this way.
4. Fancy schmancy tab completion
So that’s all great until you have 10 different hosts config files and you can’t remember their names.
The simple solution is to register additional commands so that command line tab completion can be used. The following additional script registers all the available hosts configs as separate commands. So instead of typing
hs test we can type
hstest. More importantly we can type
hs then hit the “tab” key twice and get a full list of all available commands (one per configuration file).
Hard to explain, easier to just do. Add the following lines of code to the end of your
# Setup hs* commands
if [ -d $HSPATH ]; then
for (( HSI=0 ; $HSI < $HSCOUNT ; HSI=$HSI+1 )); do
alias hs$HSFILE='hs '$HSFILE
unset HSPATH HSFILES HSCOUNT HSI HSFILE
This script loops through all the files in
/usr/local/share/hs and adds a command for each. Once that is added, reload your profile to make the script work.
$ . ~/.profile
Now you should be able to type
hs then hit the “tab” key twice and get a list of the available commands.
$ hs TAB TAB
hs hsnormal hstest
If you add any new configuration files to
/usr/local/share/hs you need to reload your profile for it to turn up as a new command (or just relaunch your terminal window).