Stephen Howells
Stephen Howells

Reputation: 929

Append line to /etc/hosts file with shell script

I have a new Ubuntu 12.04 VPS. I am trying to write a setup script that completes an entire LAMP installation. Where I am having trouble is appending a line to the /etc/hosts file. My current hosts file looks like this:

127.0.0.1       localhost Venus

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

I would like it to look like this:

127.0.0.1       localhost Venus
192.241.xx.xx  venus.example.com venus

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

I have tried a variety of sed commands using the append (\a) command. For some reason Ubuntu either just echoes the contents of the hosts file in terminal or does nothing at all. How would I properly inject the second line into the file with a bash script?

Upvotes: 76

Views: 165341

Answers (10)

NullVoxPopuli
NullVoxPopuli

Reputation: 65133

I like having named groups of shell commands when I write scripts, so that when I look at this again in 6+ months, I have a clue.

To help with naming those groups of shell commands, I use "functions" (sometimes these feel quite novel in shell scripting!)

Here is what I came up with, based on the other answers:

#!/bin/bash

function hasHostsEntry() {
  grep -n $1 /etc/hosts
}

function ensureHostsEntry() {
  local has_entry=$(hasHostsEntry $1)

  if [ -z "$has_entry" ]; then
    local fullEntry="127.0.0.1 $1"
    echo "Adding '$fullEntry' to /etc/hosts"

    echo "$fullEntry" | sudo tee -a /etc/hosts
  fi
}


ensureHostsEntry "foo.local"
ensureHostsEntry "subdomain.foo.local"

This is something that I have in a setup script in one of my project repos that I can run and idempotently have my machine setup for working with my server project.

Upvotes: 0

Matthias Schobner
Matthias Schobner

Reputation: 1240

With the following command, you can first check if the entry exists before append the new entry:

$ export NEW_HOST="192.241.xx.xx example.com"; grep -qxF $NEW_HOST /etc/hosts || echo $NEW_HOST | sudo tee -a /etc/hosts

Upvotes: 0

Mohamad Hamouday
Mohamad Hamouday

Reputation: 2753

I've developed a user-friendly script for easily adding, removing, and listing IP addresses and hostnames in the host file:

#!/bin/bash
# Created by Mohamad Hamouday
# Date: 2023-12-05
# Purpose: A script to add, remove, and list entries in the hosts file


# Function to add an entry to the hosts file
add_entry() {
    # Get user input for IP address and server name
    read -p "Enter IP address: " ip_address
    read -p "Enter server name: " server_name

    # Check if the input is not empty
    if [ -z "$ip_address" ] || [ -z "$server_name" ]; then
        echo "IP address and server name cannot be empty."
        exit 1
    fi

    # Append the entry to the hosts file
    echo "$ip_address $server_name" >> /etc/hosts

    echo "Entry added to /etc/hosts: $ip_address $server_name"
}

# Function to remove an entry from the hosts file
remove_entry() {
    # Get user input for IP address or server name to remove
    read -p "Enter IP address or server name to remove: " entry_to_remove

    # Check if the input is not empty
    if [ -z "$entry_to_remove" ]; then
        echo "Entry cannot be empty."
        exit 1
    fi

    # Check if the entry exists in the hosts file
    if grep -q "$entry_to_remove" /etc/hosts; then
        # Remove the entry from the hosts file using sed
        sed -i.bak -e "/$entry_to_remove/d" /etc/hosts

        echo "Entry removed from /etc/hosts: $entry_to_remove"
    else
        echo "Entry does not exist in /etc/hosts: $entry_to_remove"
    fi
}


# Function to list all active entries in the hosts file
list_entries() {
    echo "Non-commented entries in /etc/hosts:"
    grep -E -v '^\s*#' /etc/hosts
}


# Check if the script is executed with root privileges
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root."
   exit 1
fi

# Display menu for user choice
echo "1. Add entry"
echo "2. Remove entry"
echo "3. List entries"
read -p "Enter your choice (1, 2, or 3): " choice

case $choice in
    1)
        add_entry
        ;;
    2)
        remove_entry
        ;;
    3)
        list_entries
        ;;
    *)
        echo "Invalid choice. Exiting."
        exit 1
        ;;
esac

To execute it just run:

sudo sh scriptname.sh

Upvotes: 0

crackerjack
crackerjack

Reputation: 11

you can use sed, like:

sed '/Venus/ a\  
192.241.xx.xx  venus.example.com venus' /etc/hosts

Upvotes: 1

S Kranthi Kumar
S Kranthi Kumar

Reputation: 750

try this with root access.

 public void edithost() {
    sudo("echo " + "192.168.43.1     www.openrap.com openrap" + " >> /etc/hosts");
    sudo("echo " + "192.168.43.1  openrap.com openrap" + " >> /etc/hosts");
    sudo("echo " + "192.168.2.144  www.openrap.com openrap" + " >> /etc/hosts");
    sudo("echo " + "192.168.2.144  openrap.com openrap" + " >> /etc/hosts");
}

sudo for super user permission

public static void sudo(String... strings) {
    try {
        Process su = Runtime.getRuntime().exec("su");
        DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());

        for (String s : strings) {
            outputStream.writeBytes(s + "\n");
            outputStream.flush();
        }

        outputStream.writeBytes("exit\n");
        outputStream.flush();
        try {
            su.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

this will append the lines to hosts in the android

Upvotes: -2

Jsonras
Jsonras

Reputation: 1160

If your in mac or you need sudo permission to this try this:

sudo -- sh -c -e "echo '192.34.0.03   subdomain.domain.com' >> /etc/hosts";

It will still ask you for password.

alternative way from @kainjow

echo '192.34.0.03 subdomain.domain.com' | sudo tee -a /etc/hosts

Upvotes: 52

brismuth
brismuth

Reputation: 38402

Insert/Update Entry

If you want to programmatically insert/update a hosts entry using bash, here's a script I wrote to do that:

#!/bin/bash

# insert/update hosts entry
ip_address="192.168.x.x"
host_name="my.hostname.example.com"
# find existing instances in the host file and save the line numbers
matches_in_hosts="$(grep -n $host_name /etc/hosts | cut -f1 -d:)"
host_entry="${ip_address} ${host_name}"

echo "Please enter your password if requested."

if [ ! -z "$matches_in_hosts" ]
then
    echo "Updating existing hosts entry."
    # iterate over the line numbers on which matches were found
    while read -r line_number; do
        # replace the text of each line with the desired host entry
        sudo sed -i '' "${line_number}s/.*/${host_entry} /" /etc/hosts
    done <<< "$matches_in_hosts"
else
    echo "Adding new hosts entry."
    echo "$host_entry" | sudo tee -a /etc/hosts > /dev/null
fi

The script is intended for use with OS X but would work on linux as well with minor tweaking.

Upvotes: 41

kojiro
kojiro

Reputation: 77107

I should point out that sed (the stream editor) is not actually intended for editing files, although it can be used to do that. (Standard sed doesn't have a built-in mechanism for writing to other than standard output.) A more appropriate tool would be ed.

The following ed script says "find the line containing the (admittedly sloppy) regular expression /127.0.0.1/ and append at the next line." (The lone period tells ed to stop appending.)

ed /etc/hosts <<-'EOF'
    /127.0.0.1/a
    192.241.xx.xx  venus.example.com
    .
    wq
EOF

That said, you can really just append this line to the end of your /etc/hosts file very trivially:

echo '192.241.xx.xx  venus.example.com' >> /etc/hosts

Upvotes: 3

Vladimir Dimitrov
Vladimir Dimitrov

Reputation: 1088

echo "127.0.0.1 localhost `hostname`">./temp_hosts
echo "192.241.xx.xx  venus.example.com">>./temp_hosts
cat /etc/hosts |tail -n +2 >>./temp_hosts
cat ./temp_hosts > /etc/hosts
rm ./temp_file

Upvotes: 5

damienfrancois
damienfrancois

Reputation: 59110

Make sure to use the -i option of sed.

-i[SUFFIX], --in-place[=SUFFIX]
  edit files in place (makes backup if extension supplied)

sed -i "2i192.241.xx.xx  venus.example.com venus" /etc/hosts

Otherwise,

echo "192.241.xx.xx  venus.example.com venus" >> /etc/hosts

would append the line at the end of the file, which could work as you expect.

Upvotes: 70

Related Questions