How can I resolve a hostname to an IP address in a Bash script?

What’s the most concise way to resolve a hostname to an IP address in a Bash script? I’m using Arch Linux.

Asked By: Eugene Yarmash


With host from the dnsutils package:

$ host has address

(Corrected package name according to the comments. As a note other distributions have host in different packages: Debian/Ubuntu bind9-host, openSUSE bind-utils, Frugalware bind.)

Answered By: manatwork

You could use host:

# strips the IP
IP=$( host ${hostname} | sed -e "s/.* //" )

# checks for errors
if [ $? -ne 0 ] ; then
   echo "Error: cannot resolve ${hostname}" 1>&2
   exit 1;
Answered By: Matteo

You can use getent, which comes with glibc (so you almost certainly have it on Linux). This resolves using gethostbyaddr/gethostbyname2, and so also will check /etc/hosts/NIS/etc:

getent hosts | awk '{ print $1 }'

Or, as Heinzi said below, you can use dig with the +short argument (queries DNS servers directly, does not look at /etc/hosts/NSS/etc) :

dig +short

If dig +short is unavailable, any one of the following should work. All of these query DNS directly and ignore other means of resolution:

host | awk '/has address/ { print $4 }'
nslookup | awk '/^Address: / { print $2 }'
dig | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 }'

If you want to only print one IP, then add the exit command to awk‘s workflow.

dig +short | awk '{ print ; exit }'
getent hosts | awk '{ print $1 ; exit }'
host | awk '/has address/ { print $4 ; exit }'
nslookup | awk '/^Address: / { print $2 ; exit }'
dig | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 ; exit }'
Answered By: Chris Down

The following command using dig allows you to read the result directly without any sed/awk/etc. magic:

$ dig +short

dig is also included in the dnsutils package.

Note: dig has a return value of 0, even if the name could not be resolved. Thus, you’d need to check if the output is empty instead of checking the return value:

ip=`dig +short $hostname`

if [ -n "$ip" ]; then
    echo IP: $ip
    echo Could not resolve hostname.

Note 2: If a hostname has multiple IP addresses (try, for example), all of them will be returned. This “problem” affects all of the tools mentioned in this question so far:

Answered By: Heinzi

I have a tool on my machine that seems to do the job. The man page shows it seems to come with mysql… Here is how you could use it:

resolveip -s

The return value of this tool is different from 0 if the hostname cannot be resolved :

resolveip -s unix.stackexchange.coma
resolveip: Unable to find hostid for 'unix.stackexchange.coma': host not found
exit 2

On fedora, it comes with mysql-server :

yum provides "*/resolveip"
mysql-server-5.5.10-2.fc15.x86_64 : The MySQL server and related files
Dépôt         : fedora
Correspondance depuis :
Nom de fichier      : /usr/bin/resolveip

I guess it would create a strange dependency for your script…

Answered By: greg0ire

The solutions given so far mostly work in the simpler case: the hostname directly resolves to a single IPv4 address. This might be the only case where you need to resolve hostnames, but if not, below is a discussion on some cases that you might need to handle.

Chris Down and Heinzi briefly discussed the case where the hostname resolves to more than one IP addresses. In this case (and others below), basic scripting under the assumption that a hostname directly resolves to a single IP address may break. Below, an example with a hostname resolving to more than a single IP address:

$ host has address has address has address has address has address has address

But what is This is where the alias case needs to be introduced. Let’s check the example below:

$ host is an alias for has address has address has address has address has address has address

So does not directly resolve to IP addresses, but to an alias that itself resolves to multiple IP addresses. For more information on aliases, check here. Of course, the case where an alias has a single IP address is possible, as shown below:

$ host is an alias for has address

But can aliases be chained? The answer is yes:

$ host is an alias for is an alias for is an alias for has address

$ host is an alias for is an alias for has address has address has address has address has address has address

I did not find any example where a hostname resolves to an alias that does not resolve to an IP address, but I think the case might occur.

More than multiple IP addresses and aliases, is there some other special cases… what about IPv6? You could try:

$ host is an alias for has IPv6 address 2a00:1450:8007::68

Where the hostname is an IPv6-only hostname. What about dual-stack hostnames:

$ host has address has IPv6 address 2620:0:1c08:4000:face:b00c::

Again about IPv6, if your host is IPv4 only, you can still resolve IPv6 addresses (tested on a IPv4 only WinXP and with, you could try it on Linux). In this case, the resolution succeeds, but a ping fails with an unknown host error message. This might be a case where your scripting fails.

I hope those remarks were useful.

Answered By: jfg956
ping -q -c 1 -t 1 your_host_here | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

works without dependencies on other systems (and for hosts specified in /etc/hosts)

Answered By: Andrew McGregor

To avoid the problem with aliases and always get a single IP address ready for use:

python -c 'import socket; print socket.gethostbyname("")'
Answered By: dbernt

Here is a slight variation of the ping approach that takes “unknown host” into account (by piping through stderr) and uses tr to avoid the use of sed regexps:

ping -c1 -t1 -W0 2>&1 | tr -d '():' | awk '/^PING/{print $3}'

In case it’s important to capture the exit value, then the following will work (although less elegant):

ping -c1 -t1 -W0 &>/dev/null && ping -c1 -t1 -W0 2>&1 | tr -d '():' | awk '/^PING/{print $3}'
Answered By: Stefan Farestam
getent hosts | cut -d' ' -f1
Answered By: sborsky

here’s a Bash recipe I cooked up using other folk’s answers — first tries /etc/hosts, then falls back to nslookup:

    local host="$1"
    if [ -z "$host" ]
        return 1
        local ip=$( getent hosts "$host" | awk '{print $1}' )
        if [ -z "$ip" ] 
            ip=$( dig +short "$host" )
            if [ -z "$ip" ]
                echo "unable to resolve '$host'" >&2 
                return 1
                echo "$ip"
                return 0
            echo "$ip"
            return 0
Answered By: RubyTuesdayDONO

Simple but useful:

  1. getent ahostsv4 | grep STREAM | head -n 1 | cut -d ' ' -f 1
  2. getent ahostsv6 | grep STREAM | head -n 1 | cut -d ' ' -f 1
  3. getent hosts | head -n 1 | cut -d ' ' -f 1

All commands will resolve an IP address if the host still exists. If the host points to a CNAME it will also get the IP in that case.

The first command returns the resolved IPv4 address.

The second command returns the resolved IPv6 address.

The third command will return the owner’s preferred address, which may either an IPv4 or an IPv6 address.

Answered By: Tom Freudenberg

To complete Chris Down’s answer, and address jfgagne comments about (possibly chained) aliases, here is a solution that :

  • takes into account multiple IPs
  • takes into account one or more aliases (CNAME)
  • does not query /etc/hosts file (in my case I didn’t want it); to query it, dbernt’s python solution is perfect)
  • does not use awk/sed

    dig +short  | grep -v ".$" | head -n 1

Always returns the first IP address, or empty tring if not resolved. with version of dig :

    $ dig -v
    DiG 9.8.1-P1
Answered By: Franck
 php -r "echo gethostbyname('');"
Answered By: Mohammed Zourob

Maybe not the most concise, but it seems to be robust and efficient:

# $(get_host_dns_short "")
# Outputs the IPv4 IP Address of a hostname, resolved by DNS. Returns 0 if DNS
# responded successfully; 1 otherwise. Will mask error output.
function get_host_dns_short()
        set -o pipefail

        host -4 -W1 -t A "$1" 2>/dev/null | awk '/has address/ { print $NF; exit }'
    ) && return 0 || return 1

This will output a single IPv4 IP, as well as return 1 in the event of failure, while masking stderr output.

You can use it like this:

GOOGLE_IP="$(get_host_dns_short "")"
if [[ $? -eq 0 ]]; then
    echo "Google's IP is ${GOOGLE_IP}."
    echo "Failed to resolve Google's IP."

Google’s IP is

If you want an IPv6 address instead, just replace -4 with -6.

Answered By: Will
nmap -sP|grep YOUR_HOSTNAME|sed -n 's/.*[(]([0-9.]*)[)].*/1/p'

was the solution I found without DNS server

Answered By: Philippe Gachoud
dig  +noall +answer +nocomments | awk '{printf "%-36st%sn", $1, $5 }'
Answered By: D P Baker

I would have liked to add this as a comment to Andrew McGregor Re: ping. However it wouldn’t let me, so I need to add this as another answer. (If somebody can move it into a comment, feel free to.)

This is another variant, only using ping and grep:

ping -q -c1 -t1 your_host_here | grep -Eo "([0-9]+.?){4}"

grep -E for extended regular expression and
grep -o to return only the matching part.
the regexp itself looks for one or multiple digits ([0-9]+) and optionally a dot (.?) four times ({4})

Answered By: Dweia

1 line resolve a list of hostname

for LINE in `cat ~/Desktop/mylist`; do a=$(nslookup $LINE | awk '/^Address: / { print $1 }');  echo $a >> ~/Desktop/ip; done
Answered By: Andy Wong

I am doing this all the time on my Mac which does not have getent. ping seems like a hack. I would like to take /etc/hosts into account as well.

So, I wrote a stupid wrapper for dns.lookup for you who have Node.js installed to provide a CLI:

$ npm install -g lookup-hostname
$ lookup
Answered By: Thomas Jensen

I don’t know the easiest way for a bash-script but if you want to resolve a hostname and see if the host is up, use ping!

ping -a hostname -c 1

Will ping the host one time and resolve the hostname to IP-address.

$ ping -a -c 1
PING ( 56(84) bytes of data.
64 bytes from ( icmp_seq=1 ttl=54 time=1.51 ms
Answered By: user257655

dig is too slow, nslookup is much faster

nslookup | grep -Po 'Address:s*[0-9.]+' | tail -1 | sed -e 's/Address:s*//g'
Answered By: Andrey Izman
host -t a

this command will show ip address ( will reslove domain to IP )

Answered By: aaa

Yes, there are many answers already, but a solution using perl is missing:

perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)'

In a bash script it could be used like this:

ipaddr=$(perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)'
echo $ipaddr

Modules used here are core modules, so should be available everywhere without installing with CPAN.

Answered By: Slaven Rezic

systemd-resolve -t A  | awk '{ print $4 ; exit }'
systemd-resolve -t A --legend=no | awk '{ print $4 ; exit }'

resolveip -s
dig       +short
host     | awk '/has address/ { print $4 }'
nslookup | awk '/^Address: /  { print $2 }'
ping -q -c 1 -t 1 | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

ruby     -rresolv -e      ' print    Resolv.getaddress "" '
python2  -c 'import socket; print socket.gethostbyname("")'
perl     -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)'  2>/dev/null
php      -r "echo gethostbyname( '' );"

echo        "   all do work for me - take your pick!  "
Answered By: dotbit

Besides above solution, you can translate multiple host name to ip via below script, the only dependency is “ping” command in core Unix:

getip(){ ping -c 1 -t 1 $1 | head -1 | cut -d ' ' -f 3 | tr -d '()' 2>&1 | tee >> /tmp/result.log & }

getip ''

getip ''

getip ''

getip ''

getip ''

getip ''

getip ''

getip ''
$ cat /tmp/result.log









Answered By: Kevin

A python3 based variant that displays all ipv4 and ipv6 addresses from the system dns resolver, each ip as a separate line:

python3 -c 'import socket, sys; print("n".join([x[4][0] for x in socket.getaddrinfo(sys.argv[1], 0, type=socket.SocketKind.SOCK_STREAM)]))'

If sensible error handling is needed this would need an additional try: block etc.

Answered By: textshell
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.