Skip to content

Instantly share code, notes, and snippets.

@irazasyed
Created March 7, 2015 09:16
Show Gist options
  • Save irazasyed/a7b0a079e7727a4315b9 to your computer and use it in GitHub Desktop.
Save irazasyed/a7b0a079e7727a4315b9 to your computer and use it in GitHub Desktop.
Bash Script to Manage /etc/hosts file for adding/removing hostnames.
#!/bin/sh
# PATH TO YOUR HOSTS FILE
ETC_HOSTS=/etc/hosts
# DEFAULT IP FOR HOSTNAME
IP="127.0.0.1"
# Hostname to add/remove.
HOSTNAME=$1
function removehost() {
if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
then
echo "$HOSTNAME Found in your $ETC_HOSTS, Removing now...";
sudo sed -i".bak" "/$HOSTNAME/d" $ETC_HOSTS
else
echo "$HOSTNAME was not found in your $ETC_HOSTS";
fi
}
function addhost() {
HOSTNAME=$1
HOSTS_LINE="$IP\t$HOSTNAME"
if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
then
echo "$HOSTNAME already exists : $(grep $HOSTNAME $ETC_HOSTS)"
else
echo "Adding $HOSTNAME to your $ETC_HOSTS";
sudo -- sh -c -e "echo '$HOSTS_LINE' >> /etc/hosts";
if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
then
echo "$HOSTNAME was added succesfully \n $(grep $HOSTNAME /etc/hosts)";
else
echo "Failed to Add $HOSTNAME, Try again!";
fi
fi
}
@ingenieromora
Copy link

In line 30 I added:

sudo -- sh -c -e "echo -e '$HOSTS_LINE' >> /etc/hosts";

And in the last line I added: "$@" to run it doing:

./manage-etc-hosts.sh addhost $HOSTNAME

@BatmanAoD
Copy link

BatmanAoD commented Jun 14, 2016

I don't think the HOSTS_LINE is correct. 127.0.0.1 is generally given the hostname localhost, so simply adding 127.0.0.1\t$HOSTNAME will result in two lines with the same IP address, which I believe is not a valid configuration. On my machine, the hostname is given the address 127.0.1.1 instead. A better approach might be to simply search-and-replace for the hostname rather than deleting the line, so that the same IP address is re-used.

@olissongs
Copy link

olissongs commented Dec 16, 2016

for ubuntu 16.04. this changes worked for me
change sh to bash
changing arg 1 to 2 (arg1 is the function)
droping hostname from addhost

#!/bin/bash

# copy from https://gist.github.com/irazasyed/a7b0a079e7727a4315b9

# PATH TO YOUR HOSTS FILE
ETC_HOSTS=/etc/hosts

# DEFAULT IP FOR HOSTNAME
IP="127.0.0.1"

# Hostname to add/remove.
HOSTNAME=$2

removehost() {
    echo "removing host";
    if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
    then
        echo "$HOSTNAME Found in your $ETC_HOSTS, Removing now...";
        sudo sed -i".bak" "/$HOSTNAME/d" $ETC_HOSTS
    else
        echo "$HOSTNAME was not found in your $ETC_HOSTS";
    fi
}

addhost() {
    echo "adding host";
    HOSTS_LINE="$IP\t$HOSTNAME"
    if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
        then
            echo "$HOSTNAME already exists : $(grep $HOSTNAME $ETC_HOSTS)"
        else
            echo "Adding $HOSTNAME to your $ETC_HOSTS";
            sudo -- sh -c -e "echo '$HOSTS_LINE' >> /etc/hosts";

            if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
                then
                    echo "$HOSTNAME was added succesfully \n $(grep $HOSTNAME /etc/hosts)";
                else
                    echo "Failed to Add $HOSTNAME, Try again!";
            fi
    fi
}

$@

@rburhum
Copy link

rburhum commented Apr 20, 2017

I was always getting 127.0.0.1 as the host number that was added, so I changed IP to $3 and it started working for me.

#!/bin/bash

# copy from https://gist.github.com/irazasyed/a7b0a079e7727a4315b9

# PATH TO YOUR HOSTS FILE
ETC_HOSTS=/etc/hosts

# DEFAULT IP FOR HOSTNAME
IP=$3

# Hostname to add/remove.
HOSTNAME=$2

removehost() {
    echo "removing host";
    if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
    then
        echo "$HOSTNAME Found in your $ETC_HOSTS, Removing now...";
        sudo sed -i".bak" "/$HOSTNAME/d" $ETC_HOSTS
    else
        echo "$HOSTNAME was not found in your $ETC_HOSTS";
    fi
}

addhost() {
    echo "adding host";
    HOSTS_LINE="$IP\t$HOSTNAME"
    if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
        then
            echo "$HOSTNAME already exists : $(grep $HOSTNAME $ETC_HOSTS)"
        else
            echo "Adding $HOSTNAME to your $ETC_HOSTS";
            sudo -- sh -c -e "echo '$HOSTS_LINE' >> /etc/hosts";

            if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
                then
                    echo "$HOSTNAME was added succesfully \n $(grep $HOSTNAME /etc/hosts)";
                else
                    echo "Failed to Add $HOSTNAME, Try again!";
            fi
    fi
}

$@

@stoggi
Copy link

stoggi commented Jul 31, 2017

I would use tee -a to append to the hosts file instead of sudo sh.

printf "%s\t%s\n" "$IP" "$HOSTNAME" | sudo tee -a /etc/hosts > /dev/null

This way only tee needs to run with root privileges, instead of spawning a new shell as root. Using printf you can format the whole line and use \t without having to rely on echo -e.

@oojacoboo
Copy link

oojacoboo commented Sep 10, 2017

Updated this a bit. It will now not remove subdomains. I also made other improvements.

#!/usr/bin/env bash

# Path to your hosts file
hostsFile="/etc/hosts"

# Default IP address for host
ip="127.0.0.1"

# Hostname to add/remove.
hostname="$2"

yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }

remove() {
    if [ -n "$(grep -p "[[:space:]]$hostname" /etc/hosts)" ]; then
        echo "$hostname found in $hostsFile. Removing now...";
        try sudo sed -ie "/[[:space:]]$hostname/d" "$hostsFile";
    else
        yell "$hostname was not found in $hostsFile";
    fi
}

add() {
    if [ -n "$(grep -p "[[:space:]]$hostname" /etc/hosts)" ]; then
        yell "$hostname, already exists: $(grep $hostname $hostsFile)";
    else
        echo "Adding $hostname to $hostsFile...";
        try printf "%s\t%s\n" "$ip" "$hostname" | sudo tee -a "$hostsFile" > /dev/null;

        if [ -n "$(grep $hostname /etc/hosts)" ]; then
            echo "$hostname was added succesfully:";
            echo "$(grep $hostname /etc/hosts)";
        else
            die "Failed to add $hostname";
        fi
    fi
}

$@

@sw-Oldeu
Copy link

sw-Oldeu commented Sep 13, 2017

I like it, but grep -p is not available. Use grep -P instead 😄

#!/usr/bin/env bash

# Path to your hosts file
hostsFile="/etc/hosts"

# Default IP address for host
ip="127.0.0.1"

# Hostname to add/remove.
hostname="$2"

yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }

remove() {
    if [ -n "$(grep -P "[[:space:]]$hostname" /etc/hosts)" ]; then
        echo "$hostname found in $hostsFile. Removing now...";
        try sudo sed -ie "/[[:space:]]$hostname/d" "$hostsFile";
    else
        yell "$hostname was not found in $hostsFile";
    fi
}

add() {
    if [ -n "$(grep -P "[[:space:]]$hostname" /etc/hosts)" ]; then
        yell "$hostname, already exists: $(grep $hostname $hostsFile)";
    else
        echo "Adding $hostname to $hostsFile...";
        try printf "%s\t%s\n" "$ip" "$hostname" | sudo tee -a "$hostsFile" > /dev/null;

        if [ -n "$(grep $hostname /etc/hosts)" ]; then
            echo "$hostname was added succesfully:";
            echo "$(grep $hostname /etc/hosts)";
        else
            die "Failed to add $hostname";
        fi
    fi
}

$@

@anilchejarla
Copy link

hello haiii..
can you please send me for " Printing only Ip address and hostname " by using shellscript.

@anilchejarla
Copy link

hello haiii..
Any one can please send me for " Printing only Ip address and hostname " by using shellscript.
to this mail.: [email protected]

@Fuxy22
Copy link

Fuxy22 commented Jan 10, 2018

Re-factored this a bit and turned them into simple functions you can just paste into your .bash_aliases and most importantly you can use whatever IP you want say the one from your vagrant box for instance see bash_aliases.sh

@cbig75
Copy link

cbig75 commented Apr 25, 2019

Hi, could someone explain me how to use this script on a Mac please ?

Copy link

ghost commented Jan 24, 2021

I like it, but grep -p is not available. Use grep -P instead

#!/usr/bin/env bash

# Path to your hosts file
hostsFile="/etc/hosts"

# Default IP address for host
ip="127.0.0.1"

# Hostname to add/remove.
hostname="$2"

yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }

remove() {
    if [ -n "$(grep -P "[[:space:]]$hostname" /etc/hosts)" ]; then
        echo "$hostname found in $hostsFile. Removing now...";
        try sudo sed -ie "/[[:space:]]$hostname/d" "$hostsFile";
    else
        yell "$hostname was not found in $hostsFile";
    fi
}

add() {
    if [ -n "$(grep -P "[[:space:]]$hostname" /etc/hosts)" ]; then
        yell "$hostname, already exists: $(grep $hostname $hostsFile)";
    else
        echo "Adding $hostname to $hostsFile...";
        try printf "%s\t%s\n" "$ip" "$hostname" | sudo tee -a "$hostsFile" > /dev/null;

        if [ -n "$(grep $hostname /etc/hosts)" ]; then
            echo "$hostname was added succesfully:";
            echo "$(grep $hostname /etc/hosts)";
        else
            die "Failed to add $hostname";
        fi
    fi
}

$@

On running the above script as follows (i.e second argument is empty), the contents od the entire /etc/hosts file gets removed

sh manage-etc-hosts.sh remove 

Attaching the script with a small fix

#!/usr/bin/env bash

# Path to your hosts file
hostsFile="/etc/hosts"

# Default IP address for host
ip="0.0.0.0"

# Hostname to add/remove.
hostname="$2"

yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }

if [ -z "$1" ] || [ -z "$2" ]; then
   die "Exiting... invalid arguments";
fi

remove() {
    if [ -n "$(grep -w "$hostname$" /etc/hosts)" ]; then
        echo "$hostname found in $hostsFile. Removing now...";
        try sudo sed -ie "/[[:space:]]$hostname/d" "$hostsFile";
    else
        yell "$hostname was not found in $hostsFile";
    fi
}

add() {
    if [ -n "$(grep -P "[[:space:]]$hostname" /etc/hosts)" ]; then
        yell "$hostname, already exists: $(grep $hostname $hostsFile)";
    else
        echo "Adding $hostname to $hostsFile...";
        try printf "%s\t%s\n" "$ip" "$hostname" | sudo tee -a "$hostsFile" > /dev/null;

        if [ -n "$(grep $hostname /etc/hosts)" ]; then
            echo "$hostname was added succesfully:";
            echo "$(grep $hostname /etc/hosts)";
        else
            die "Failed to add $hostname";
        fi
    fi
}

$@

References

@pauky
Copy link

pauky commented Apr 14, 2021

I use this to resolve my problem.

#!/bin/sh

# run:
# ./manage-etc-hosts.sh add 10.20.1.2 test.com
# ./manage-etc-hosts.sh remove 10.20.1.2 test.com

# PATH TO YOUR HOSTS FILE
ETC_HOSTS=/etc/hosts


function remove() {
    # IP to add/remove.
    IP=$1
    # Hostname to add/remove.
    HOSTNAME=$2
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
    then
        echo "$HOSTS_LINE Found in your $ETC_HOSTS, Removing now...";
        sudo sed -i".bak" "/$HOSTS_LINE/d" $ETC_HOSTS
    else
        echo "$HOSTS_LINE was not found in your $ETC_HOSTS";
    fi
}

function add() {
    IP=$1
    HOSTNAME=$2
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    line_content=$( printf "%s\t%s\n" "$IP" "$HOSTNAME" )
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
        then
            echo "$line_content already exists : $(grep $HOSTNAME $ETC_HOSTS)"
        else
            echo "Adding $line_content to your $ETC_HOSTS";
            sudo -- sh -c -e "echo '$line_content' >> /etc/hosts";

            if [ -n "$(grep -P $HOSTNAME $ETC_HOSTS)" ]
                then
                    echo "$line_content was added succesfully";
                else
                    echo "Failed to Add $line_content, Try again!";
            fi
    fi
}

$@

@lemyskaman
Copy link

changing the console from sh to bash worked for me like a charm in ubuntu 20.04

#!/bin/bash

# run:
# ./manage-etc-hosts.sh add 10.20.1.2 test.com
# ./manage-etc-hosts.sh remove 10.20.1.2 test.com

# PATH TO YOUR HOSTS FILE
ETC_HOSTS=/etc/hosts


function remove() {
    # IP to add/remove.
    IP=$1
    # Hostname to add/remove.
    HOSTNAME=$2
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
    then
        echo "$HOSTS_LINE Found in your $ETC_HOSTS, Removing now...";
        sudo sed -i".bak" "/$HOSTS_LINE/d" $ETC_HOSTS
    else
        echo "$HOSTS_LINE was not found in your $ETC_HOSTS";
    fi
}

function add() {
    IP=$1
    HOSTNAME=$2
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    line_content=$( printf "%s\t%s\n" "$IP" "$HOSTNAME" )
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
        then
            echo "$line_content already exists : $(grep $HOSTNAME $ETC_HOSTS)"
        else
            echo "Adding $
```line_content to your $ETC_HOSTS";
            sudo -- sh -c -e "echo '$line_content' >> /etc/hosts";

            if [ -n "$(grep -P $HOSTNAME $ETC_HOSTS)" ]
                then
                    echo "$line_content was added succesfully";
                else
                    echo "Failed to Add $line_content, Try again!";
            fi
    fi
}

$@

@raaka9890
Copy link

how do we solve the problem of password prompt. Every time i run the script it ask for password. I dont want to enter the password manually. Has any one solved this problem???

@pauky
Copy link

pauky commented Aug 9, 2021

how do we solve the problem of password prompt. Every time i run the script it ask for password. I dont want to enter the password manually. Has any one solved this problem???

Do you mean password prompt when you use sudo command?
https://phpraxis.wordpress.com/2016/09/27/enable-sudo-without-password-in-ubuntudebian/

@nielsvanzon
Copy link

changing the console from sh to bash worked for me like a charm in ubuntu 20.04

#!/bin/bash

# run:
# ./manage-etc-hosts.sh add 10.20.1.2 test.com
# ./manage-etc-hosts.sh remove 10.20.1.2 test.com

# PATH TO YOUR HOSTS FILE
ETC_HOSTS=/etc/hosts


function remove() {
    # IP to add/remove.
    IP=$1
    # Hostname to add/remove.
    HOSTNAME=$2
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
    then
        echo "$HOSTS_LINE Found in your $ETC_HOSTS, Removing now...";
        sudo sed -i".bak" "/$HOSTS_LINE/d" $ETC_HOSTS
    else
        echo "$HOSTS_LINE was not found in your $ETC_HOSTS";
    fi
}

function add() {
    IP=$1
    HOSTNAME=$2
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    line_content=$( printf "%s\t%s\n" "$IP" "$HOSTNAME" )
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
        then
            echo "$line_content already exists : $(grep $HOSTNAME $ETC_HOSTS)"
        else
            echo "Adding $
```line_content to your $ETC_HOSTS";
            sudo -- sh -c -e "echo '$line_content' >> /etc/hosts";

            if [ -n "$(grep -P $HOSTNAME $ETC_HOSTS)" ]
                then
                    echo "$line_content was added succesfully";
                else
                    echo "Failed to Add $line_content, Try again!";
            fi
    fi
}

$@

I think you made a typo here
echo "Adding $ ```line_content to your $ETC_HOSTS";

should be this I guess:
echo "Adding $line_content to your $ETC_HOSTS";

@Ran-Xing
Copy link

how do we solve the problem of password prompt. Every time i run the script it ask for password. I dont want to enter the password manually. Has any one solved this problem???

chmod 666 /etc/hosts

@ceelian
Copy link

ceelian commented Mar 25, 2023

Thanks for the scripts. I tried them but these scripts are adding new lines even though the same IP already exists. This does not conform with the /etc/hosts format and can cause issues.

Therefore I created a script that adds the hostname to the IP address line if the IP already exists in the hosts file. Only if it doesn't exist, a new line will be added. Gist is here: https://gist.github.com/ceelian/0c293cf0e10c924a2124e2c9fa3805a9

@kucerarichard
Copy link

Thanks for the scripts. I tried them but these scripts are adding new lines even though the same IP already exists. This does not conform with the /etc/hosts format and can cause issues.

Therefore I created a script that adds the hostname to the IP address line if the IP already exists in the hosts file. Only if it doesn't exist, a new line will be added. Gist is here: https://gist.github.com/ceelian/0c293cf0e10c924a2124e2c9fa3805a9

this script does't remove, we need that. thanks!

For example I can't use experimental podman on an old host, so I have to build and use httperf directly and try to add host aliases without being too cumbersome:

add_host_alias "host:ip" && httperf ... && remove_host_alias "host:ip"

@kucerarichard
Copy link

kucerarichard commented Sep 13, 2023

Productionized for my use of httperf. Tested a bit.

#!/bin/bash

# Synopsis:
# ./alterhost.sh add-host test.com:1.2.3.4
# ./alterhost.sh add-host 'test.com:1.2.3.4;test2.com:2.3.4.5;test3.com:3.4.5.6'
# ./alterhost.sh del-host test.com:1.2.3.4
# ALTER_VERBOSE=t ./alterhost.sh del-host test.com:1.2.3.4

if test $# -lt 2 ; then
echo "USAGE: alterhost <verb> '<name:ip;name:ip;name:ip...>' "
echo 'EX: ./alterhost.sh add-host test.com:1.2.3.4'
echo "EX: ./alterhost.sh add-host 'test.com:1.2.3.4;test2.com:2.3.4.5;test3.com:3.4.5.6'"
echo 'EX: ./alterhost.sh del-host test.com:1.2.3.4'
echo 'EX: ALTER_VERBOSE=t ./alterhost.sh del-host test.com:1.2.3.4'
echo "EX: ./alterhost.sh add-host 'www.test.org:2.3.5.6' ;  httperf --server www.test.org --uri /LICENSE.txt --num-conns 10 --rate 10 --timeout 10 --hog --ssl ; ./alterhost.sh del-host 'www.test.org:2.3.5.6'"
exit -1
fi

# PATH TO YOUR HOSTS FILE
#ETC_HOSTS=/etc/hosts
ETC_HOSTS=./test_etc_hosts

[ ! -f $ETC_HOSTS.bak2 ] && cp -p $ETC_HOSTS $ETC_HOSTS.bak2

function msg() {
  MESSAGE=$1
  if [[ -z "${ALTER_VERBOSE}" ]]; then
     exit 0
  else
     echo $MESSAGE
  fi
}

function del-host() {
  for i in $(echo $1 | sed -e 's/;/\n/g'); do
    readarray -t HOSTIP < <(echo $i | awk -F':' '{print $1; print $2}')
    IP=${HOSTIP[1]}
    HOSTNAME=${HOSTIP[0]}
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
    then
        msg "${HOSTIP[*]} Found in your $ETC_HOSTS, Removing now..."
        sudo sed -i".bak" "/$HOSTS_LINE/d" $ETC_HOSTS
    else
        msg "${HOSTIP[*]} was not found in your $ETC_HOSTS"
    fi
  done
}

function add-host() {

  for i in $(echo $1 | sed -e 's/;/\n/g'); do
    readarray -t HOSTIP < <(echo $i | awk -F':' '{print $1; print $2}')
    IP=${HOSTIP[1]}
    HOSTNAME=${HOSTIP[0]}
    HOSTS_LINE="$IP[[:space:]]$HOSTNAME"
    line_content=$( printf "%s\t%s\n" "$IP" "$HOSTNAME" )
    if [ -n "$(grep -P $HOSTS_LINE $ETC_HOSTS)" ]
        then
            msg "$line_content already exists : $(grep $HOSTNAME $ETC_HOSTS)"
        else
            msg "Adding $line_content to your $ETC_HOSTS";
            sudo -- sh -c -e "echo '$line_content' >> $ETC_HOSTS";

            if [ -n "$(grep -P $HOSTNAME $ETC_HOSTS)" ]
                then
                    msg "$line_content was added succesfully";
                else
                    msg "Failed to Add $line_content, better take a look!";
                    exit -1
            fi
    fi
  done
}

$@

@cjgordon
Copy link

cjgordon commented Jul 28, 2024

@kucerarichard in your script I needed to change the msg function from 'exit 0' to 'return' so that it wouldn't exit unless run with verbose flag.

function msg() {
MESSAGE=$1
if [[ -z "${ALTER_VERBOSE}" ]]; then
exit 0
else
echo $MESSAGE
fi
}

To:

function msg() {
   MESSAGE=$1
   if [[ -z "${ALTER_VERBOSE}" ]]; then
      return
   else
      echo $MESSAGE
   fi
 }

@tuaris
Copy link

tuaris commented Aug 28, 2024

What would be the downside/danger of looking at grep's exit code instead of comparing strings?

if grep -q $HOSTNAME /etc/hosts; then 
  # Entry already exists
else
   # Add in the entry
fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment